NHibernate Issues之1255:联合主键(composite-id)

发布时间:2026/7/6 3:48:56
NHibernate Issues之1255:联合主键(composite-id) .Domain这里定义一个Domain——CustomerValue这个持久化类有两个属性联合主键(composite-id)和Value。我们使用联合主键首先需要定义联合主键的类型同时这个类必须重载Equals()和GetHashCode()方法来实现组合的标识符等同性判断。 例如下面的CustomerValue持久化类其联合主键类型为CustomerValueId就是Customer持久化类与int类型的复合形式在CustomerValueId类中重载了Equals()和GetHashCode()方法。public class Customer { public virtual int Id { get; set; } public virtual string Name { get; set; } } public class CustomerValue { public virtual CustomerValueId Id { get; set; } public virtual decimal Value { get; set; } } public class CustomerValueId : IEquatableCustomerValueId { private int? _requestedHashCode; public Customer Customer { get; set; } public int CustomKey { get; set; } public bool Equals(CustomerValueId other) { if (ReferenceEquals(null, other)) { return false; } if (ReferenceEquals(this, other)) { return true; } return Equals(other.Customer, Customer) other.CustomKey CustomKey; } public override bool Equals(object obj) { if (ReferenceEquals(null, obj)) { return false; } if (ReferenceEquals(this, obj)) { return true; } if (obj.GetType() ! typeof(CustomerValueId)) { return false; } return Equals((CustomerValueId)obj); } public override int GetHashCode() { if (!_requestedHashCode.HasValue) { unchecked { _requestedHashCode ((Customer ! null ? Customer.GetHashCode() : base.GetHashCode()) * 397) ^ CustomKey; } } return _requestedHashCode.Value; } }2.Mapping需要对两个Domain映射这里注重理解下联合主键的映射这里是把类的Customer属性和CustomerKey属性组合成为标识符属性。key-many-to-one节点用于映射子元素一般都是Domain(多对一关系的)key-property节点用于映射属性。在这里我需要在key-many-to-one节点中设置not-found attribute来避免在运行时抛出异常就是设置not-foundignore。class nameCustomer id nameId generator classhilo / /id property nameName / /class class nameCustomerValue composite-id nameId classCustomerValueId key-many-to-one nameCustomer columnCustomerId not-foundignore / key-property nameCustomKey / /composite-id property nameValue / /class3.Test做完了上面的步骤测试一下保存一个CustomerValue。查询验证下并删除。这个测试很简单就不贴出SQL结果了。using (var session OpenSession()) { using (var tx session.BeginTransaction()) { var customer new Customer { Name 李永京 }; session.Save(customer); var customerValue new CustomerValue { Id new CustomerValueId { Customer customer, CustomKey 20012 }, Value 1255.0m }; session.Save(customerValue); tx.Commit(); } using (var tx session.BeginTransaction()) { var customerValue session.CreateQuery(from CustomerValue c where c.Value:value) .SetDecimal(value, 1255.0m) .UniqueResultCustomerValue(); session.Delete(customerValue); session.Delete(from Customer); tx.Commit(); }