问题
Update: It appears that changing my mapping from Cascade.All() to Cascade.AllDeleteOrphan() fixes most of my issues. I still have to explicitly set the Company property on the OperatingState, which seems unnecessary as it's being added to the Company entity, but at least I can work with that during an update. I still need to test that with a create.
If any one can explain that, that would be a big help.
Update 2: After playing with it some more, it appears I don't always have to specify the parent entity.
Original Post
I have 2 related entities
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; }
}
And they are mapped like this:
 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);
        }
 }
So all is well until I try to update Company with new Operating States
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
It bombs out with:
Cannot insert the value NULL into column 'CompanyID', table 'ConsumerCartel.dbo.CompanyOperatingState'; column does not allow nulls. INSERT fails. The statement has been terminated.
However, if I make 2 changes it kind of works
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
Which will add the new states in addition to the old ones, which is not what I want. However, even when explicitly setting the company (which I shouldn't have to do when it's added to a mapped list?) it doesn't work if the list is cleared.
This code has worked on other entities, but not on this one, so I think this should work as written. What am I doing wrong?
回答1:
Have you tried using Inverse()?
HasMany(x => x.OperatingStates)
    .Inverse()
    .Cascade.All()
    .Table("OperatingState");
    来源:https://stackoverflow.com/questions/1512738/fluent-nhibernate-hasmany-collection-problems