我有两个名为Country和City的简单实体。
public class Country : Entity
{
public Country()
{
Cities = new List<City>();
}
public virtual string Name { get; set; }
public virtual IList<City> Cities { get; set; }
}
public class City : Entity
{
public virtual Country Country { get; set; }
public virtual string Name { get; set; }
}
使用的数据库是SQL Server,城市有一个带有级联删除的国家/地区的外键。
我正在使用Fluent NHibernate,这是关系的映射配置:
public CountryMap()
{
Id(x => x.Id, "IdCountry").GeneratedBy.Identity();
Map(x => x.Name).Not.Nullable().Length(50);
HasMany(x => x.Cities).KeyColumn("IdCountry").ForeignKeyConstraintName("FK_Cities_Countries")
.Not.KeyNullable().Cascade.AllDeleteOrphan().ExtraLazyLoad();
Table("Countries");
}
public CityMap()
{
Id(x => x.Id, "IdCity").GeneratedBy.Identity();
Map(x => x.Name).Not.Nullable().Length(50);
References(x => x.Country, "IdCountry").ForeignKey("FK_Cities_Countries")
.Not.Nullable().Not.Insert().Not.Update().Cascade.All().LazyLoad();
Table("Cities");
}
一切正常,但删除国家/地区后,城市仍保留在父系列中,我希望从该系列中删除城市。 (正如EF所做的那样)
我找到让它运作的唯一方法是刷新会话(Clear,Evict ......)
答案 0 :(得分:1)
使用这种映射,最简单的方法是从Country集合中删除City并保存Country。通过级联,城市将被删除,收集将处于您想要的状态。
答案 1 :(得分:1)
手动删除收集项目不是解决方案。它实际上打破了cascading
功能。
如果我们确实有 Cascade.AllDeleteOrphan()
的映射,我们应该会删除 Parent 也会删除 Children - 否需要做更多,然后删除父。只是...... NHibernate并不关心在内存中清除该集合(app server / application)
如果您正在寻找长而稳定的固体解决方案,我强烈建议:
拆分READ和WRITE操作
我们(如Web API)的当前框架正在帮助我们朝这个方向发展。我们应该创建一组操作:
Find()
) 每个操作都应该有自己的会话,自己的交易,并且应该代表工作单元。全有或全无。操作成功并且所有操作都是持久的,或者不是(回滚)
这将有助于我们的应用程序成功并在更长/更长的时间内成长。我们分手了。我们关心
1)删除,更新或插入(或者更多的一些根实体,可以看到更多here)。 2)我们做READ操作 - 只期望SELECT操作,因此使用最新数据。另请检查this, including comments
虽然这可能有点超出范围,但这个引用形式9.8. Exception handling doc也是线索:
...如果
ISession
抛出异常,你应立即回滚事务,调用ISession.Close()
并丢弃ISession实例。某些ISession方法不会离开会议处于一致状态......
我想证明,操作 (会话,交易)应该只有一个目标(WRITE,READ)并且<强>尽可能短 ......