问题描述
||
我间歇性地收到以下异常:
拥有实体实例不再引用具有cascade = \“ all-delete-orphan \”的集合:Domain.Foo.Bars
Google针对此异常的大多数结果都表明,当您取消引用集合而不是在现有集合上调用Clear()然后添加新实体时,就会出现此问题。但是,这不是我的问题。
这是所有相关代码:
public class Foo
{
public int Id { get; set; }
private Iesi.Collections.Generic.ISet<Bar> _bars = new HashedSet<Bar>();
public virtual ICollection<Bar> Bars
{
get { return _bars; }
}
}
public class Bar
{
public int Id { get; set; }
public DateTime Expiry { get; set; }
}
public class FooDbMap : ClassMap<Foo>
{
public FooDbMap
{
Id(x => x.Id);
HasMany(x => x.Bars)
.Access.CamelCaseField(Prefix.Underscore)
.KeyColumn(\"FooId\")
.LazyLoad()
.Where(\"Expiry > (select getdate())\")
.AsSet()
.Cascade.AllDeleteOrphan();
}
}
您将通过此代码看到无法取消引用Bars集合,即通过执行以下操作:
foo.Bars = new List<Boo>();
是什么导致错误?
解决方法
您永远不应将NHibernate创建的集合引用弄乱。首先,NH创建用于延迟加载的代理对象-用List <>替换该代理,并且NH无法延迟加载内容或检测是否删除了任何子代。其次,NH监视映射的集合的更改(新实体,删除等)。仅用NH不知道的新集合替换一个集合不是一个好主意。 NH仍将引用托管集合,尤其是如果您让NH监视此集合并将所有更改层叠到所包含的子代时,尤其如此。
我只需要清除集合即可删除所有实体,而不是替换整个集合。