[英]Data Context's SubmitChanges method causing a entity reference to be set to null
我知道这看起来有点长,但我试图尽可能地解释这个问题。
我们对linq to sql数据上下文类有一个非常“异乎寻常”的问题。 我们有一个n层结构,结构如下:我们有3个类MotherClass,ChildClass,ChildChildrenClass
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; }
}
}
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; }
}
}
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; }
}
}
当我们对ChildClass对象进行更新并删除与之关联的一些ChildChildrenClass项时,会出现问题。代码如下所示:
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
上面提到的问题是cclass.Mother属性被神奇地设置为null。 在经过大量调试(在Mother set方法中显示刹车点后发现这一点)后,我们注意到在某些外部代码中SubmitChanges()期间该属性被设置为null。
SubmitChanges()方法成功完成(删除了ChildChildrenClass项)但这会导致在此之后运行的代码出现问题。 我们使用相同的DataContext(因为事务)并再次调用抛出此异常的SubmitChanges()方法:
System.InvalidOperationException:尝试删除MotherClass和ChildClass之间的关系。 但是,其中一个关系的外键(ChildClass.MotherId)不能设置为null。 在System.Data.Linq.ChangeTracker.StandardChangeTracker.StandardTrackedObject.SynchDependentData()处于System.Data.Linq.ChangeProcessor.ValidateAll(IEnumerable`1列表)的System.Data.Linq.ChangeProcessor.SubmitChanges(ConflictMode failureMode)处于System.Data的System.Data.Linq.ChangeTracker.StandardChangeTracker.StandardTrackedObject.SynchDependentData() .Linq.DataContext.SubmitChanges(ConflictMode failureMode)
很久以前,当我写博客引擎时,我也遇到过这个问题。 从连接表中删除了几行后出现了问题。 删除这些东西没关系,那么无论我做了什么,下一个SubmitChanges()
出现这个确切的异常。
在花了大约一天左右的时间解决问题后,我重新解决了一个问题:
我知道这非常 hacky,但这是我解决它的唯一方法。 我看到你在那里使用了一个交易,这会让这更难一点。 也许尝试使用两个不同的事务(一个用于旧的DataContext,一个用于新的),如果第二个失败,则回滚第一个事务?
我知道这很黑。
也许尝试使用另一个没有问题的ORM(例如NHibernate)。
不要使用LinQ-To-SQL,因为
永远不应该重用DataContext
实例。 每次因为框架无法确保在SubmitChanges()
调用之间没有更改数据,建议的方法是在提交更改后处理DataContext并在另一个需要SubmitChanges()
事务时创建一个新的DataContext需要打电话。
此外, DataContext
对象已经包装了事务中的任何插入,更改和/或删除。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.