更新: マッピングを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
それは爆撃します:
列'CompanyID'、テーブル'ConsumerCartel.dbo.CompanyOperatingState'に値NULLを挿入できません。列はnullを許可しません。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
これにより、古い状態に加えて新しい状態が追加されますが、これは私が望んでいることではありません。ただし、会社を明示的に設定する場合でも(マップされたリストに追加するときに行う必要はありませんか?)、リストがクリアされていると機能しません。
このコードは他のエンティティでは機能しましたが、このエンティティでは機能しなかったため、これは記述どおりに機能するはずです。私は何が間違っているのですか?