当前位置: 首页 > news >正文

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 : IEquatable<CustomerValueId> { 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-found="ignore"。

<class name="Customer"> <id name="Id"> <generator class="hilo" /> </id> <property name="Name" /> </class> <class name="CustomerValue" > <composite-id name="Id" class="CustomerValueId"> <key-many-to-one name="Customer" column="CustomerId" not-found="ignore" /> <key-property name="CustomKey" /> </composite-id> <property name="Value" /> </class>

3.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) .UniqueResult<CustomerValue>(); session.Delete(customerValue); session.Delete("from Customer"); tx.Commit(); }
http://www.gsyq.cn/news/1644397.html

相关文章:

  • BetterNCM安装器:让网易云音乐插件安装变得像点外卖一样简单
  • 推荐几个好用到哭的小清新APP
  • MSF 反弹 Shell 实战教程:从生成木马到获取服务器权限
  • Redis——分布式锁
  • 计组面试--h自用
  • Lua--协同线程与文件IO
  • 小红书博主都在偷偷用的AI工具,不用懂代码就能自动运营
  • 智能办公本X2:端侧AI驱动的手写语音协同工作流
  • Lua--基础入门
  • 2000+机柜怎么管?数据中心U位资产管理方案拆解
  • 完整RAG工作流达成!手把手教你使用NAS部署企业生产级AI知识库
  • 库存并发安全控制的架构设计
  • 谷歌两款AI学习工具大揭秘:NotebookLM与Learn About谁更胜一筹?
  • 别再硬写提示词了!LangChain PromptTemplate从入门到实战
  • GEO代理接单后总部负责落地吗
  • PowerShell 路径规则详解:从基础到高级
  • 2026杭州初中毕业女生暑假学什么好?选对方向比努力更重要
  • 剪映专业版教程:制作西施跳广场舞效果
  • MLflow在LLM评估中的工程实践:实现可追溯、可比较、可归因的模型管理
  • 06-高级模式与实战项目——01. Render Props - 共享渲染逻辑
  • TFT-LCD 驱动架构对比:4 种 Cs 存储电容布局的优缺点与选型指南
  • 私密科普:女性经后淋漓不尽,别当成普通经期残留
  • 机房故障换机后应急验证:24 小时 SpeedCE 点检 SOP
  • AI编程助手实战指南:从原理到应用,GitHub Copilot与Cursor深度测评
  • 白话MVP
  • Cline 配置 Claude Sonnet 5 实战指南:思考深度调优与切换 Fable 5 的时机
  • Redis--Redis分布式系统的原理与实操
  • 图最短路评测:Dijkstra 对了,也可能用错场景
  • 74LS73 异步计数器设计实战:2片芯片实现4位二进制与8421BCD电路对比
  • [特殊字符] Git 协作指南