nhibernate 4.0中的双向关系

我有一个代码在NHibernate 3.1上完美运行,但是当它不能在NHibernate 4.0上运行时

所以,这就是阶级关系

public class Employee : BaseEntity { ... public Department Dept { get; set; } } public class Department : BaseEntity { ... public IList Employees { get; set; } } 

对于映射,我们有这个

 DepartmentMap : ClassMap { Table("...."); HasMany(x => x.Employees).KeyColumn("DeptId").Not.KeyNullable(); } EmployeeMap : ClassMap { Reference(x => x.Dept).Column("DeptId"); } 

当我添加这样的员工时

 var dept = session.Load(deptId); newEmployee.Dept = dept; session.Save(newEmployee); 

但这是一个错误:

NHibernate.PropertyValueException:not-null属性引用null或transient值

我读到我必须以两种方式添加关系,所以我将其修改为此

 var dept = session.Load(deptId); newEmployee.Dept = dept; dept.Employees.Add(newEmployee); session.Save(newEmployee); 

但现在我有这个错误:

NHibernate.PropertyValueException:错误使…的属性值脱水.System.IndexOutOfRangeException:此SqlParameterCollection的索引7无效,Count = 7。

所以,我想知道如何修复它以及我可以在哪里阅读有关双向的NHibernate变化

第一个问题 – 双向映射

我们应该始终指定关系的双方。 好吧, 总是?!? 这是优秀的做法。

但是 ,如果我们想使用.Load()来检索parent (Department) – 我们应该指定parent.Chidren.Add()

Load()是如何获取“假”(代理)实例的聪明方式,仅由该实体的ID表示(很难创建正确的INSERT语句)

所以,在这种情况下我们应该避免dept.Employees.Add(newEmployee); – 我们根本不需要加载部门

 // existing parent - but NHibernate just creates a proxy with expected ID var dept = session.Load(deptId); // child Employee is provided with parent reference - it is enough newEmployee.Dept = dept; // this will not help, just will execute SELECT - no benefit // dept.Employees.Add(newEmployee); // save and it should work session.Save(newEmployee); 

第二个(真实)问题 – 双重映射

虽然它在问题代码片段中不可见,但我敢打赌,Employee实际上有这个def和映射

 public class Employee : BaseEntity { ... // reference public virtual Department Dept { get; set; } // reference_ID also mapped as integer public virtual int? DeptId { get; set; } } EmployeeMap : ClassMap { Reference(x => x.Dept).Column("DeptId"); Map(x => x.DeptId) // with .Not.Nullable() by code or convention ; } 

所以 – 我们在C#中有两个属性属于一个SQL列。 我会说,这绝对没问题,但我们必须确保我们稍微调整一下。 整数应该可以为空并且必须是只读的

 EmployeeMap : ClassMap { Reference(x => x.Dept).Column("DeptId"); Map(x => x.DeptId) .Nullable() .Insert(false) .Update(false); // as far as I rememeber syntax to replicate // 
		      	

我找到了解决问题的方法:解决问题的方法是将Inverse添加到父文件的映射中。 因此,部门的映射将是:

 DepartmentMap : ClassMap { Table("...."); HasMany(x => x.Employees).KeyColumn("DeptId").Inverse().Not.KeyNullable(); }