2009-10-03 74 views
1

更新: 看來,將我的映射從Cascade.All()更改爲Cascade.AllDeleteOrphan()修復了我的大部分問題。我仍然必須在OperatingState上明確地設置公司屬性,這似乎是不必要的,因爲它被添加到公司實體中,但至少我可以在更新期間使用它。我仍然需要用創建來測試。流利的NHibernate HasMany收集問題

如果任何人可以解釋,那將是一個很大的幫助。

更新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'; 列不允許有空值。 INSERT 失敗。該聲明已被終止 。

但是,如果我做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 

將在另外添加新的狀態,以舊的,這不是我想要的。但是,即使在明確設置公司(我將其添加到映射列表時,我不應該這樣做)的情況下,也可以使用,但如果清除列表,則不起作用。

此代碼已在其他實體上工作,但不在這一個,所以我認爲這應該工作作爲書面。我究竟做錯了什麼?

回答

2

您是否嘗試過使用Inverse()?

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

感謝您的回答。實際上,.Inverse是幫助我引入.AllDeleteOrphan()選項的原因。 – 2009-10-05 14:51:03