Method Data Context SubmitChanges, causing the installation of an entity reference

I know this looks a little long, but I tried to explain the problem as much as I could.

We are having a very "exotic" problem with the linq to sql data context class. We have an n-tier architecture, structured as follows: we have 3 classes MotherClass, ChildClass, ChildChildrenClass

MotherClass looks something like this:

public class MotherClass { private EntitySet<ChildClass> _Children; [Column] public int Id { get; set; } [Association(Storage = "_Children", ThisKey = "Id", OtherKey = "MotherId")] public EntitySet<ChildClass> Children { get { return _Children; } set { _Children= value; } } } 

And ChildClass looks something like this:

 public class ChildClass { private EntityRef<MotherClass> _Mother; private EntitySet<ChildChildrenClass> _ChildChildren; [Column] public int Id { get; set; } [Column] public int MotherId { get; set; } [Association(Storage = "_Mother", IsForeignKey = true, ThisKey = "MotherId", OtherKey = "Id")] public MotherClass Mother { get { return _Mother.Entity; } set { _Mother.Entity = value; } } [Association(Storage = "_ChildChildren", ThisKey = "Id", OtherKey = "ChildId", DeleteRule = "NO ACTION")] public EntitySet<ChildChildrenClass> ChildChildren { get { return _ChildChildren; } set { _ChildChildren= value; } } } 

And the third class, magically called ChildChildrenClass:

 public class ChildChildrenClass { private EntityRef<ChildClass> _Child; [Column] public int Id { get; set; } [Column] public int ChildId { get; set; } [Association(Storage = "_Child", IsForeignKey = true, ThisKey = "ChildId", OtherKey = "Id")] public ChildClass Child { get { return _Child.Entity; } set { _Child.Entity = value; } } } 

The problem occurs when updating the ChildClass object and deleting some of the ChildChildrenClass elements associated with it. The code looks something like this:

 DataContext dc = new DataContext(conStr); dc.StartTransaction();//our custom method for handling transactions ChildClass cclass = dc.ChildClass.GetById(id);//our method for getting the ChildClass from db //... here we set some values we want to edit //... //... dc.SubmitChanges(ConflictMode.FailOnFirstConflict);//these actions are cool //after this the problems arise List<ChildChildrenClass> ccc = GetAllChildren();//method that gets all the childChildrenClass objects from db foreach (ChildChildrenClass child in ccc) { dc.GetTable(child.GetType()).DeleteOnSubmit(child); } dc.SubmitChanges(ConflictMode.FailOnFirstConflict); //AFTER CALLING THIS METHOD THE PROBLEM APPEARS 

The problem mentioned above is that the cclass.Mother property is magically set to null. After much debugging (placing bracepoints in the Mother set method revealed this), we noticed that the property is null during SubmitChanges () in some external code.

The SubmitChanges () method completed successfully (ChildChildrenClass elements removed), but this causes a problem with the code that runs after that. We use the same DataContext (due to the transaction) and call the SubmitChanges () method again, which throws this exception:

System.InvalidOperationException: An attempt was made to remove the relationship between MotherClass and ChildClass. However, one of the foreign relationship keys (ChildClass.MotherId) cannot be null. in System.Data.Linq.ChangeTracker.StandardChangeTracker.StandardTrackedObject.SynchDependentData () in System.Data.Linq.ChangeProcessor.ValidateAll (IEnumerable`1 list) in System.Data.Linq.ChangeProcessor.Submittode.DataModeMangata.DataModemata .Linq.DataContext.SubmitChanges (ConflictMode failureMode)

+6
c # linq-to-sql datacontext
source share
3 answers

I also encountered this problem a long time ago when I wrote a blog block. The problem arose after I deleted a couple of rows from the connection table. Removing things went well, then no matter what I did, this exact exception appeared on the next SubmitChanges() .

After spending about one day or so, having solved the problem, I settled on a workaround:

  • Create a new instance of the DataContext
  • Get a new instance of any objects used in the new DataContext

I know these are very hacks, but that was the only way to solve the problem. I see you are using a transaction there, which would make it a little more complicated. Perhaps try using two different transactions (one for the old DataContext and one for the new) and rollback the first if the second failed?
I know this is hacking.

Perhaps try using another ORM (e.g. NHibernate) that has no problem with this.

+2
source share

Do not use LinQ-To-SQL because

  • It is discontinued by Microsoft
  • This is a good tool, but only for very simple domains. This has its own relationship problems.
  • There are many alternatives. If you need ADO.NET Entity Framework time design support. if you have a complex domain for matching NHibernate, which is also a great constancy of ignorance. There are also many subsonic fans there.
+1
source share

DataContext instances should never be used. Each time, since the structure cannot guarantee that the data has not been changed between SubmitChanges() calls, the recommended approach is to get rid of the DataContext after the changes have been submitted and create a new one if another transaction requiring SubmitChanges() call required.

In addition, the DataContext object already wraps any insertions, changes, and / or deletes transactions.

+1
source share

All Articles