I am making a very simple Lightswitch project which will connect to a table I have in an Oracle 11g database. I add an editable grid to the project and build the project. When I try to add or edit data in the grid I get the following error:
An error occurred while starting a transaction on the provider connection. See the inner exception for details.
Inner exception message:
Connection is already part of a local or a distributed transaction
There is no custom code in the project. My perception was that Lightswitch was supposed to make forms over data very easy. I've looked around for help but nothing so far.
//You need to clean up or the txn will fail..
partial void SaveChanges_Executed()
{
tx.Complete();
tx.Dispose();
}
If you get this error, "Inner exception message: Connection is already part of a local or a distributed transaction"
you can resolve the issue by following the second post by BScholz, https://forums.oracle.com/forums/thread.jspa?threadID=2263095
Basically, you need to implement SaveChanges_Excuting and SaveChanges_Excuted for the Oracle Data Source.
Switch to "File View" (LightSwitch will display "Logical View" by default).
Add a reference to "System.Transactions" in Server project.
Switch back to "Logical View"
Right Click the Data Source Name and click "View Code" to edit partial class.
Copy-and-paste the code below:
private TransactionScope _tscope;
partial void SaveChanges_Executing()
{
_tscope = new TransactionScope(TransactionScopeOption.Required,
new TransactionOptions
{
IsolationLevel = System.Transactions.IsolationLevel.ReadCommitted
});
}
partial void SaveChanges_Executed()
{
_tscope.Complete();
_tscope.Dispose();
}
Try adding this code to your datasource code. (right click on the Oracle datasource and choose "View Code")
Make sure you remember to change the class name to match your datasource.
using System.Transactions;
namespace LightSwitchApplication
{
public partial class <ChangeThisToYourClassName>
{
private TransactionScope tx;
partial void SaveChanges_Executed()
{
tx.Complete();
}
partial void SaveChanges_Executing()
{
tx = new TransactionScope(TransactionScopeOption.Required,
new TransactionOptions {
IsolationLevel = System.Transactions.IsolationLevel.ReadCommitted
});
}
}
}
Related
I've read multiple questions similar to this one but none are exactly my situation.
Using linq-to-sql I insert a new record and submit changes. Then, in the same web request, I pull that same record, and update it, then submit changes. The changes are not saved. The DatabaseContext is the same across both these operations.
Insert:
var transaction = _factory.CreateTransaction(siteId, userId, questionId, type, amount, transactionId, processor);
using (IUnitOfWork unitOfWork = UnitOfWork.Begin())
{
transaction.Amount = amount;
_transactionRepository.Add(transaction);
unitOfWork.Commit();
}
Select and Update:
ITransaction transaction = _transactionRepository.FindById(transactionId);
if (transaction == null) throw new Exception(Constants.ErrorCannotFindTransactionWithId.FormatWith(transactionId));
using (IUnitOfWork unitOfWork = UnitOfWork.Begin())
{
transaction.CrmId = crmId;
transaction.UpdatedAt = SystemTime.Now();
unitOfWork.Commit();
}
Here's the unit of work code:
public virtual void Commit()
{
if (_isDisposed)
{
throw new ObjectDisposedException(GetType().Name);
}
_database.SubmitChanges();
}
I even went into the designer.cs file and put a breakpoint on the field that is being set but not updated. I stepped through and it entered and execute the set code, so the Entity should be getting "notified" of the change to this field:
public string CrmId
{
get
{
return this._CrmId;
}
set
{
if ((this._CrmId != value))
{
this.OnCrmIdChanging(value);
this.SendPropertyChanging();
this._CrmId = value;
this.SendPropertyChanged("CrmId");
this.OnCrmIdChanged();
}
}
}
Other useful information:
ObjectTracking is enabled
No errors or exceptions when second SubmitChanges is called (just silently fails update)
SQL profiler shows insert and select but not the subsequent update statement. Linq-To-Sql is not generating the update statement.
There is only one database, one database string, so the update is not going to another database
The table has a primary key.
I don't know what would cause Linq-To-Sql to not issue the update command and not raise some kind of error. Perhaps the problem stems from using the same DataContext instance? I've even refreshed the object from the database using the DataContact.Refresh method before it is pulled for the update, but that didn't help.
I have found what is likely to be the root cause. I am using Unity. The initial insert is being performed in a service class with a PerWebRequest lifetime. The select and update is happening in a class with a Singleton lifetime. So my assumption that the DataContext instances are the same was incorrect.
So, in my class with the Singleton lifetime, I get a fresh instance of the database repository and perform the update and no problem.
Now I still don't know why the original code didn't work and my approach could still be considered more a workaround than a solution, but it did solve my problem and hopefully will be useful to others.
Hello In my solution I've' got a class library named 'EntityFrameworkModel' AND here i add
ADO.NET ENTITY DATA MODEL. So my .edmx model perfectly created.
In my other project in this solution - which is asp,net project, in my web form here is what I do
I add the reference to my class library with the .edmx model
I add the
using EntityFrameworkModel ;directive
I make one really simple function
public void LoadTourists()
{
var db = new excursionEntities();
foreach (var tourist in db.Tourists)
{
lblproba.Text += tourist.Name_kir.ToString();
}
}
which I call on page_Load.
But I keep getting the above error
I am new to Tridion Event System. I have written a small code.
[TcmExtension("MyEventHandlerExtension")]
public class EH : TcmExtension
{
public EH()
{
Subscribe();
}
public void Subscribe()
{
//EventSystem.Subscribe<Component, DeleteEventArgs>(HandlerForInitiated, EventPhases.Initiated);
EventSystem.Subscribe<Tridion.ContentManager.CommunicationManagement.Page, Tridion.ContentManager.Extensibility.Events.PublishOrUnPublishEventArgs>(HandlerForCommitted, EventPhases.All);
}
private void HandlerForCommitted(IdentifiableObject subject, PublishOrUnPublishEventArgs args, EventPhases phase)
{
TDSE obj = new TDSE();
Tridion.ContentManager.Interop.TDS.Publication pub = obj.GetPublication("tcm:0-150-1");
Tridion.ContentManager.Interop.TDS.Page pubPage = obj.GetPage("tcm:150-12374-64", pub);
pubPage.Publish("tcm:0-1-65538", false, true, false, default(DateTime), default(DateTime), default(DateTime));
}
}
using this code i wanted to publish a page everytime when a publish and unpublish event occur.
I build this code and register its path in tridion config file .
But its not working.Please Help
Ok, first of all remove all your TDSE code, you should use TOM.NET. You can get session as subject.Session
Then make sure you have registered this extension in Tridion.ContentManager.config and restarted your system
And finally - if something doesn't work, just add simple code that will create a file in your HandlerForCommitted whenever event occurs, this way you will be able to see if your extension get executed.
The 2011 Event System uses the TOM.NET API and not the TOM API. Please do not create new TDSE objects in the 2011 Event System. Even though you can reference the old Interop libraries, there is no reason to do so with 2011. Using the TOM.NET libraries you should see better performance and also the code is future-proof.
Mihai Cadariu has a nice example where he uses TOM.NET to Publish a page from a Tridion Template. Adjusting the code to check for previewmode or publish mode and setting your own user and priority (instead of reading it from the current transaction) should work well.
Below code from http://yatb.mitza.net/2012/05/publishing-from-template-code-using.html
public void Publish(Engine engine, String tcmUri, User user, PublishPriority priority)
{
Session session = new Session(user.Title);
PublishInstruction publishInstruction = new PublishInstruction(session);
RenderInstruction renderInstruction = new RenderInstruction(session);
renderInstruction.RenderMode = RenderMode.Publish; // work around. needs to be specified for binaries.
publishInstruction.RenderInstruction = renderInstruction;
List<IdentifiableObject> items = new List<IdentifiableObject>() { session.GetObject(tcmUri) };
List<PublicationTarget> targets = new List<PublicationTarget>() { engine.PublishingContext.PublicationTarget };
PublishEngine.Publish(items, publishInstruction, targets, priority);
session.Dispose();
}
// called with
PublishTransaction currentTransaction = TemplateUtils.GetPublishTransaction(engine);
TemplateUtils.Publish(engine, itemUri, currentTransaction.Creator, currentTransaction.Priority);
Your code seems to have the three things I "normally" forget:
the class is public
it extends TcmExtension
it has a TcmExtension attribute
If you've registered the class correctly in the configuration file, it should just be a matter of restarting the relevant module(s). In this case I'd expect those to be the Publisher and TcmServiceHost services.
After restarting those modules and triggering a publish action, you should see an event being logged (in the Windows event viewer) that your extension is being loaded.
If that even shows, it means your assembly is being loaded into the relevant Tridion process and the class is being recognized and instantiated.
If at this stage your handler doesn't fire you may have to consider listening to a different event. Whenever I want to interact with the publishing, I end up listening for the SaveEventArgs of a PublishTransaction, instead of the PublishOrUnPublishEventArgs on the Page.
I want to make a simple Silverlight application in ASP.NET and LINQ. I have two talbe
Student :[student_id,student_name,address, phone,country_id] Country
:[country_id,country_name]
Thiw tow table is join by country_id.
I have inluced a LINQ Data Class in my project.
I have included a Silverlight-Enabled-WCF-Serfice. In this service I have made tow method and there code is like
[OperationContract]
public List<Country> LoadCountry()
{
var result = from coun in oLINQDataClassesDataContext.Countries
select coun;
return result.ToList();
}
[OperationContract]
public IList<Student> LoadStudent()
{
var result = from std in oLINQDataClassesDataContext.Students
select std;
return result.ToList();
}
Then I add a service reference of that WCF service. Then I include a DataGrid in my silverlight .xml file.
Now I want to show all the students in that DataGrid. For this I have written the following code
WCFServiceReference.WCFServiceClient oWCFServiceClient = new WCFServiceReference.WCFServiceClient();
public Home()
{
InitializeComponent();
oWCFServiceClient.LoadStudentCompleted += new EventHandler<WCFServiceReference.LoadStudentCompletedEventArgs>(oWCFServiceClient_LoadStudentCompleted);
oWCFServiceClient.LoadStudentAsync();
}
void oWCFServiceClient_LoadStudentCompleted(object sender, WCFServiceReference.LoadStudentCompletedEventArgs e)
{
dataGrid1.ItemsSource = e.Result;
}
Then I build the whole project and found no error. If I run the project then I found an error and it is--
An exception occurred during the operation, making the result invalid.
Check InnerException for exception details. at
System.ComponentModel.AsyncCompletedEventArgs.RaiseExceptionIfNecessary()
at
Silverlight.WCFServiceReference.LoadStudentCompletedEventArgs.get_Result()
at Silverlight.Home.oWCFServiceClient_LoadStudentCompleted(Object
sender, LoadStudentCompletedEventArgse) at
Silverlight.WCFServiceReference.WCFServiceClient.OnLoadStudentCompleted(Object
state)
If I remove county table form the LINQ class and remove LoadCountry() method form the service and call LoadStudent() method form silverlight form then it runs accurately and all the data is displayed in my DataGrid.
If I remove student table form the LINQ class and remove LoadStudent() method form the service then LoadCountry() method runs accurately. Both methods are not work if the present same time in LINQ & WCF Service .
NB: Both tables has data. If I run a SQL join query then it returns data
I can’t understand what the problem is.
Is there anyone to help me regarding this problem?
Thanks in advance.
Rashed
go to properties of dbml file and change the Serialization mode to unidirectional
I am develloping a web form that has a wizard with 4 steps:
On each step I'me creating new entities generated from a database.
The problem is that being a wizzard, the user can change the properties of the controls that will originate the values to be stored.
So I need to release the created entity objects or return that entity values to the original rows stored on the database.
How can I do this.
Should'n it work if I set each created entity object to null?
By the way this is how I'm doing it:
entities = new Entities();
...
Client client = new Client();
client.name = tbxName.text
...
entities.SaveChanges();
entities.Connection.Close();
So If this code is executed on the 2nd wizard part of a wizard of 3 parts and I go back and fowrward through this set more the once the client creating runs more than once, so there's my problem.
So how can I unCreate it :-P
Thannks!!!
If you are building wizard you must manage it as single operation. It means that you have to store built entity graph in the session and save it only if whole wizard is completed and confirmed. Your step logic also must check if related data are already present in the entity graph and use them instead of creating new one.
If your using Entity Framework, why not implement the Unit Of Work pattern? Each part of your wizard builds the UoW and the "final step" commits the unit of work.
There was an article called "The Unit Of Work Pattern And Persistence Ignorance" in MSDN magazine a few years ago that explains the concept.
This is the way I do it:
1- Create a place where you can manage your Session variables :
public class SessionObjects { }
2- I save my ObjectContext in the Session so I create a property to manage it in the mentioned class :
public static ObjectContextEntities ObjectContextEntities
{
get
{
return (ObjectContextEntities)HttpContext.Current.Session["ObjectContextEntities"];
}
set
{
HttpContext.Current.Session["ObjectContextEntities"] = value;
}
}
3- Initialize the ObjectContext on the wizard's start and dispose it on its end:
void StartWizard()
{
SessionObject.ObjectContextEntities = new ObjectContextEntities();
}
void StartWizard()
{
SessionObject.ObjectContextEntities = new ObjectContextEntities();
}
void EndWizard()
{
((ObjectContextEntities)SessionObject.ObjectContextEntities).Dispose();
}
4- To save wizard result to the database you can call:
void SaveWizard()
{
((ObjectContextEntities)SessionObject.ObjectContextEntities).SaveAllChanges();
}
5- To reset wizard simply call EndWizard then StartWizard .
I guess you know how to manage your ObjectEntity objects and in the ObjectContext so you can continue from here by your self ..