更新: 似乎将我的映射从 Cascade.All() 更改为 Cascade.AllDeleteOrphan() 解决了我的大部分问题。我仍然必须在 OperatingState 上显式设置 Company 属性,这似乎没有必要,因为它被添加到 Company 实体中,但至少我可以在更新期间使用它。我仍然需要通过创建来测试它。
如果有人能解释这一点,那将是一个很大的帮助。
更新 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
除了旧状态之外,这将添加新状态,这不是我想要的。但是,即使明确设置公司(将其添加到映射列表时我不应该这样做?)如果列表被清除,它也不起作用。
此代码已在其他实体上运行,但不适用于此,因此我认为这应该按书面方式运行。我究竟做错了什么?