对已删除的集合项进行Nhibernate
本文关键字:Nhibernate 集合 删除 | 更新日期: 2023-09-27 18:14:11
我有两个类:
public class Entry{
...
public virtual IsDeleted {get;set;}
public virtual int MyClsId {get;set;}
public virtual MyClass MyCls {get;set;}
}
public class MyClass{
...
public virtual ICollection<Entry> Entries {get;set;}
}
当我从MyClass中移除一个项目时。我不想删除它,也不想终止关系。我只想设置条目。IsDeleted为true,我仍然希望条目保持myClass的Id;
myClassObj.Entries.Remove(myEntry); // after this line myEntry.MyCls.Id
// should stay intact. myEntry.IsDeleted
// should be set to true;
我该怎么做呢?我试过拦截器,但不能让它工作。
编辑
映射:
除了映射我使用的字段:
MyClassMap : ...
{
HasMany(x => Entries).KeyColumn("MyClsId");
}
这似乎不像你真的想从集合中删除这个,也许它会更有意义的Entry
上放一个方法,就像
public void Delete(){
IsDeleted = true;
}
而不是
myClassObj.Entries.Remove(myEntry);
myEntry.Delete();
在这种情况下,您必须更新您的实体而不是删除。尝试使用
更改映射// set cascade to all to add/update/delete this childs by parent.
HasMany(x => Entries).KeyColumn("MyClsId").Cascade.All();
在MyClass
上创建一个方法更新它:
public class MyClass{
...
public virtual ICollection<Entry> Entries {get;set;}
public void DeleteEntry(Entry entry)
{
entry.IsDelete = true;
}
}
,当你想设置一个Entry
对象为IsDeleted到true
时,你调用DeleteEntry
方法传递对象,只是持久化MyClass
实例,孩子们将一起持久化。
session.SaveOrUpdate(myClassObj);
如果我正确理解您的场景,您希望有一个Delete操作,该操作将在最后:
- 保持关系
- 标记为
IsDeleted
- 不要将其保存在父的集合中(这里我不确定,但如果需要,我们有下面的解决方案)
1)为了保持关系,我们不需要一直调用delete。
我们可以在父RemoveEntry
public class MyClass
{
public virtual void RemoveEntry(Entry entry) // or by index, name
{
// some checks over Entries collection
entry.IsDeleted = true;
}
}
当MyClass实例被更新为session.Update(myClass)
时,所有条目也将被更新
2)为了将其标记为IsDeleted
,我们只需附加级联(在这里查看更多流畅映射
MyClassMap : ...
{
HasMany(x => Entries)
.KeyColumn("MyClsId")
.Cascade.All()
}
3)要从惰性加载的Parent子集合中删除该项,可以在集合映射中附加where
子句。where子句中的映射
MyClassMap : ...
{
HasMany(x => Entries)
.KeyColumn("MyClsId")
.Cascade.All()
.Where("IsDeleted = 0"); // that will load only IsDeleted == false lazily
}
关于文档中where子句的更多信息:6.2。映射集合
实现您想要的一种方法是不直接使用实体,而是使用DTO,这是您的实体的副本(具有所有集合项)。在DTO上执行删除操作(因此已删除的集合项对应用程序是不可见的),稍后当您想要保存实体时,只需将其与DTO同步(对于已删除的集合项,将IsDeleted标志设置为true)。多做了一点工作,但它达到了你想要的效果
我必须在MyClass中创建一个额外的属性,这似乎是唯一可行的解决方案。
public virtual IEnumerable<Entry> NotDeletedEntries{get{return Entries.Where(x=>x.IsDeleted == false);}}