【发布时间】:2011-04-06 09:08:00
【问题描述】:
我知道这看起来有点长,但我试图尽可能彻底地解释这个问题。
我们在 linq to sql 数据上下文类中遇到了一个非常“奇异”的问题。我们有一个这样的 n 层架构:我们有 3 个类 MotherClass、ChildClass、ChildChildrenClass
MotherClass 看起来像这样:
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; }
}
}
而 ChildClass 看起来像:
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; }
}
}
还有神奇地命名为 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; }
}
}
当我们对 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.Linq.DataContext.SubmitChanges(ConflictMode failureMode)
【问题讨论】:
标签: c# .net linq-to-sql datacontext