更新: 看來,將我的映射從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
將在另外添加新的狀態,以舊的,這不是我想要的。但是,即使在明確設置公司(我將其添加到映射列表時,我不應該這樣做)的情況下,也可以使用,但如果清除列表,則不起作用。
此代碼已在其他實體上工作,但不在這一個,所以我認爲這應該工作作爲書面。我究竟做錯了什麼?
感謝您的回答。實際上,.Inverse是幫助我引入.AllDeleteOrphan()選項的原因。 – 2009-10-05 14:51:03