Fluent NHibernate中HasMany关联保存时外键未更新问题求助
你遇到的问题核心是**Inverse()的使用导致关联维护权转移到了子实体(Company)端**,而你只更新了父实体(Accountant)的集合,没有同步更新子实体的引用,所以NHibernate不会自动更新tblCompany的外键。
为什么会这样?
当你在AccountantMap的HasMany配置中添加了.Inverse(),这就告诉NHibernate:这个一对多关联的维护责任在多的那一方(Company)。也就是说,NHibernate只会在Company的Accountant属性被显式设置时,才会更新tblCompany中的Account_id外键。你现在只把Company对象添加到了Accountant.Companies集合里,但没有给每个Company设置Accountant引用,所以NHibernate认为这个关联没有被维护,不会生成更新外键的SQL语句。
修复步骤
1. 修改创建Accountant的代码,同步维护双向关联
在将Company添加到Accountant的集合时,必须同时给每个Company设置Accountant属性:
public void Create_Accountant() { var repo = new Repository(); var accountant = new Accountant { Name = "Accountant Simba", Companies = new List<Company>() }; // 获取第一个公司并设置关联 var company1 = repo.GetById<Company>(new Guid("02032BD9-2769-4183-9750-AF1F00A5E191")); company1.Accountant = accountant; accountant.Companies.Add(company1); // 获取第二个公司并设置关联 var company2 = repo.GetById<Company>(new Guid("F86E8B40-73D2-447E-A525-AF1F00A5E191")); company2.Accountant = accountant; accountant.Companies.Add(company2); repo.Save(accountant); }
2. 可选:优化映射配置(非必须,但更合理)
你的CompanyMap中给Accountant的References配置了.Cascade.SaveUpdate(),这个在当前场景下其实是多余的——因为你是从Accountant端发起保存,AccountantMap的.Cascade.All()已经会级联处理关联的Company对象。如果不需要从Company端保存时自动创建/更新Accountant,可以去掉这个Cascade配置:
// 修改CompanyMap中的Accountant引用配置 References(x => x.Accountant); // 去掉.Cascade.SaveUpdate()
额外说明
Inverse()是用来避免双向关联时NHibernate生成重复的SQL语句,它的核心作用是明确关联的维护方。在一对多关联中,通常推荐将维护方设置为多的一端(也就是这里的Company),因为这样可以减少不必要的数据库操作,但这也要求你在代码中同时维护双向的关联关系——既要把子实体加到父实体的集合,也要给子实体设置父实体的引用。
内容的提问来源于stack exchange,提问作者McMaribo

