流利的NHibernate HasMany收集问题

时间:2009-10-03 03:51:41

标签: c# nhibernate fluent-nhibernate domain-driven-design bdd

更新 似乎将我的映射从Cascade.All()更改为Cascade.AllDeleteOrphan()修复了我的大部分问题。我仍然需要在OperatingState上明确设置Company属性,这似乎是不必要的,因为它被添加到Company实体,但至少我可以在更新期间使用它。我仍然需要用create来测试它。

如果有人可以解释,那将是一个很大的帮助。

更新2:在玩了更多内容之后,似乎我并不总是需要指定父实体。

原帖

我有2个相关实体

public class Company {
        //... fields
        public virtual IList<OperatingState> OperatingStates { get; set; }
}

public class OperatingState {
        public virtual Company Company { get; set; }// Mapped on CompanyID
        public virtual string State { get; set; }
}

它们的映射如下:

 public class CompanyMap : ClassMap<Company> {
        public CompanyMap() {
        //... fields 
          HasMany(x => x.OperatingStates)
                .Cascade.All()
                .Table("OperatingState");
        }
}
 public class OperatingStateMap : ClassMap<OperatingState> {
        public OperatingStateStateMap() {
            Id(x => x.ID);
            References(x => x.Company);
            Map(x => x.State);
        }
 }

所以一切顺利,直到我尝试用新的运营状态更新公司

Company company = _repo.GetSingle(123);
 company.OperatingStates.Clear();
 foreach(string state in form["OperatingStates"].Split(',')) {
    company.OperatingStates.Add(new OperatingState(state));
 }
 _repo.Save(company); // calls ISession.SaveOrUpdate

它爆炸了:

  

无法将值NULL插入   列'CompanyID',表   'ConsumerCartel.dbo.CompanyOperatingState';   列不允许空值。插入   失败。声明一直如此   终止。

但是,如果我进行了2次更改,则可以使用

Company company = _repo.GetSingle(123);
 // don't clear the list this time;
 foreach(string state in form["OperatingStates"].Split(',')) {
    OperatingState os = new OperatingState(state);
    // explicitly setting the company
    os.Company = company;
    company.OperatingStates.Add(os);
 }
 _repo.Save(company); // calls ISession.SaveOrUpdate

除了旧的状态之外,还会添加新的状态,这不是我想要的。但是,即使明确设置公司(当它被添加到映射列表时我不应该这样做?)如果清除列表它也不起作用。

此代码适用于其他实体,但不适用于此实体,因此我认为按写入方式工作。我做错了什么?

1 个答案:

答案 0 :(得分:2)

您是否尝试过使用Inverse()?

HasMany(x => x.OperatingStates)
    .Inverse()
    .Cascade.All()
    .Table("OperatingState");