当我使用Nhibernate 3更新子项时,子项中删除的项目不会从数据库中删除。
案例描述如下
class Parent {
string Id;
string Name;
IList Children;
}
class Child {
int ChildId;
string Name;
string Value;
Parent parent;
}
hdm映射文件如下所示 Parent.hdm.xml
<bag name="Children" table="ClientsExt" inverse ="true" cascade="all-delete-orphan" lazy="false">
<key column="ChildId"/>
<one-to-many class="XXXX.Child, XXX"/>
</bag>
Child.hdm.xml
<many-to-one name="Parent" column="Id" class="XXXX.Parent, XXX" not-null="true"/>
假设现有的父母将数据库中的一组子项关联起来
Parent Table
Id = "P1", Name = "Test"
Child Table
ChildId = 1, Id="P1", Name = "N1", Value = "V1"
ChildId = 2, Id="P1",Name = "N1", Value = "V2"
ChildId = 3, Id="P1",Name = "N2", Value = "V3"
在我的情况下,我需要部分更新孩子。 在更新后的Parent需要更新记录2 设定值ChildId = 2,值=&#34; NEWVALUE&#34; 并且删除 ChildId = 1,Id =&#34; P1&#34;,Name =&#34; N1&#34;,Value =&#34; V1&#34; 和ChildId 3将保持不变。
所以我先从数据库中获取Parent,
var entity = _parentRepo.getById("P1");
var children = entity.Children;
var updatedChildren = children.ToList<Child>;
var tmpList = new List<Child>();
//biz means the business logic object which contains update info
if (biz.N1.Count > 0){
var existN1 = children.Where(x=>x.Name.Equals("N1")).Select(y=>y.ChildId);
int count = existN1.Count;
int index = 0;
biz.N1.ForEach(x=>{
if(index < count){
tmpList.Add(new Child(){ Id = existN1[index],Name="N1",Value="newValue",Parent = entity });
}else{
tmpList.Add(new Child(){ Name="N1",Value="newValue",Parent = entity });
}
});
updatedChildren.RemoveAll(x=>x.Name.Equals("N1"));
updateChildren.AddRange(tmpList);
}
entity.Children = updateChildren;
//Save the entity
但是,在数据库中,记录2将值更新为&#34; NEWVALUE&#34;,但没有删除ChildId = 1,Id =&#34; P1&#34;,Name =& #34; N1&#34;,值=&#34; V1&#34; 。 为什么呢?
提前感谢。
答案 0 :(得分:1)
发生了什么,是上面的代码打破了 session 原则,拆分了链。每当我们希望NHibernate做出明智的决定时,我们必须始终保持基础的东西。这不符合:
var children = entity.Children;
var updatedChildren = children.ToList<Child>; // a brand new NHibernate-detached coll
...
// operations out of the scope of the NHiberante session
...
entity.Children = updateChildren; // broken chain of information
在幕后,NHibernates将自己的智能系列放入entity.Children
属性。它正在跟踪有关更改(已删除元素,已更改...)的信息,因此如果要求它保留更改... NHibernate知道......
如果我们把全新的,断开连接的集合,NHibernate很难找到,有一些元素缺失。无法如何发出DELETE。
解决方案:始终使用entity.Children
引用。然后我们会得到我们需要的......