NHibernate联合主键详细示例
使用NHibernate实现一对多,多对一的关联很是简单,可如果要用复合主键实现确实让人有些淡淡的疼。虽然很淡疼但还是要去抹平这个坑,在下不才,愿意尝试。
以示例进入正文,源码下载地址:
一、数据表关系图
很明显,他是一个自引用数表,实现无限级树结构的存储。
二、关键步骤
- 注解如何实现复合主键
根据官方文档说明,联合主键最好是一个独立的类,需要重载Equals和GetHashCode方法,且标记为可序列化。代码如下:
[Serializable]
public class BaseInfo
{
public virtual string Id { get; set; }
public virtual string GroupNumber { get; set; } public override bool Equals(object obj)
{
var baseInfo = obj as BaseInfo;
if (baseInfo == null)
{
return false;
} return baseInfo.Id == this.Id && baseInfo.GroupNumber == this.GroupNumber;
}
public override int GetHashCode()
{
return base.GetHashCode();
}
}
- 子类配置好联合主键
[CompositeId(, Name = "BN")]
[KeyProperty(, Name = "Id", Column = "Id", TypeType = typeof(string))]
[KeyProperty(, Name = "GroupNumber", Column = "GroupNumber", TypeType = typeof(string))]
public virtual BaseInfo BN { get; set; }
说明:
1.实现为引用BaseInfo类,而不是继承.
- 实现一对 和 多对一的映射
这步没有多大难度,主要处理好注解的顺序即可,以及OneToMany时联合主键如何设置的问题.示例代码如下:
[Bag(, Name = "Childs", Cascade = "all", Lazy = CollectionLazy.False, Inverse = true)]
[Key()]
[Column(, Name = "ParentId")]
[Column(, Name = "GroupNumber")]
[OneToMany(, ClassType = typeof(Foo))]
public virtual IList<Foo> Childs { get; set; } [ManyToOne(, Name = "Parent", ClassType = typeof(Foo))]
[Column(, Name = "ParentId")]
[Column(, Name = "GroupNumber")]
public virtual Foo Parent { get; set; }
三、出错了,有Bug
- childs没有数据
重载的GetHashCode方法有问题,返回值应该是联合主键HashCode,优化后的实现如下:
public override int GetHashCode()
{
return (this.Id + "|" + this.GroupNumber).GetHashCode(); //判断缓存是否存在,已此作为Key
}
- 插入数据时报错,提示SqlParameterCollection的索引无效[索引溢出错误]
原因,最初在设计Parent的时候,与联合主键共用了一个字段GroupNumber,导致在NHibernate做映射转换的时候会多计算出一个需要填充的值,但SqlParameterCollection中又少一个位置。优化代码如下:
//外键与联合主键不要共用字段
[ManyToOne(, Name = "Parent", ClassType = typeof(Foo))]
[Column(, Name = "ParentId")]
[Column(, Name = "ParentGroupNumber")]
public virtual Foo Parent { get; set; }
说明:
1.由于联合外键与联合主键共用了一个字段,导致映射出错
四、终于实现了,总结
- 类都必须可以序列化,也就是要还serializable标注
- 继承BaseInfo实现联合主键(不推荐使用)
在Save时,如果用session.merge方法组合缓存与修改对象,返回值的主键会为Null
- 联合主键与联合外键字段不能重复,也不能共用
- 注意重载的GetHashCode和Equals方法
- GetHashCode返回实例的惟一标识
- Equals判断是否相同实例的具体实现
NHibernate联合主键详细示例的更多相关文章
- NHibernate composite-id联合主键配置
NHibernate的联合主键配置比较复杂,初次配置可能需要花些时间,但只要我们理解了,掌握一定的步骤还是很容易的. 1.设计数据结构 Users:用户表 名称 Users 说明 用户表 序号 字段名 ...
- NHibernate 映射基础(第三篇) 简单映射、联合主键
NHibernate 映射基础(第三篇) 简单映射.联合主键 NHibernate完全靠配置文件获取其所需的一切信息,其中映射文件,是其获取数据库与C#程序关系的所有信息来源. 一.简单映射 下面先来 ...
- Hibernate(5)—— 联合主键 、一对一关联关系映射(xml和注解) 和 领域驱动设计
俗话说,自己写的代码,6个月后也是别人的代码……复习!复习!复习!涉及的知识点总结如下: One to One 映射关系 一对一单向外键(XML/Annotation) 一对一双向外键关联(XML/A ...
- SQL联合主键 查重
2014年最后一天,今天在给数据库导入数据的时候,遇到一个问题,就是联合主键去重. 事情是这样的,现有一个表M,我想找个表中导入了许多数据,并需要将字段A(int)和B(int)联合设置为主键. 但是 ...
- Hibernate注解映射联合主键的三种主要方式
今天在做项目的时候,一个中间表没有主键,所有在创建实体的时候也未加组件,结果报以下错误: org.springframework.beans.factory.BeanCreationException ...
- 联合主键用Hibernate注解映射的三种方式
第一.将联合主键的字段单独放在一个类中,该类需要实现java.io.Serializable接口并重写equals和hascode,再将该类注解为@Embeddable,最后在主类中(该类不包含联合主 ...
- EntityFramework中Mapper怎么定义联合主键?
HasKey(m => new { m.StoreId, m.CarTypeId, m.CarLevel}) 用“new {}”联合主键以“,”分隔形式定义
- SQL Server中的联合主键、聚集索引、非聚集索引、mysql 联合索引
我们都知道在一个表中当需要2列以上才能确定记录的唯一性的时候,就需要用到联合主键,当建立联合主键以后,在查询数据的时候性能就会有很大的提升,不过并不是对联合主键的任何列单独查询的时候性能都会提升,但我 ...
- sql,联合主键,按id分组求版本号最大值的集合
表结构如下: /* SQLyog v10.2 MySQL - 5.5.39 ************************************************************** ...
随机推荐
- Oracle中注意用户的访问权限
新增表.序列.存储过程等,要注意用户(例如System)的权限.如果在增删改查过程中出现数据库读写权限的报错,则在建表(或者序列.存储过程等)时,在脚本前面加 GRANT CREATE TABLE T ...
- 单独一个img标签的居中显示
针对页面当中通过img插入图片的时候,要保证这个图片在页面内容当中居中,一般的做法是在外面套一个div,通过给div加入 {margin:0 auto;} 来控制图片的居中. 那么如果针对后台上传的图 ...
- Js Date泣血整理
原文:Js Date泣血整理 JS Date 对象用于处理日期和时间. 创建 Date 对象的语法: var myDate=new Date() Date 对象会自动把当前日期和时间保存为其初始值. ...
- Strongly connected(hdu4635(强连通分量))
/* http://acm.hdu.edu.cn/showproblem.php?pid=4635 Strongly connected Time Limit: 2000/1000 MS (Java/ ...
- 赠书《JavaScript高级程序设计(第三版)》5本
本站微博上正在送书<JavaScript高级程序设计>走过路过的不要错过,参与方式,关注本站及简寻网+转发微博:http://weibo.com/1748018491/DoCtp6B8r ...
- Android最新支持包Design简介
Android 5.0 Lollipop是曾经最著名的Android发布之一,这样说很大一部分原因是材料设计的引入,而材料设计则是一种刷新了整个Android体验的设计语言.这个详细说明是开始适应材料 ...
- SpringMVC表单标签
SpringMVC学习系列(11) 之 表单标签 本篇我们来学习Spring MVC表单标签的使用,借助于Spring MVC提供的表单标签可以让我们在视图上展示WebModel中的数据更加轻松. ...
- VS2013 Update 2正式发布 .NET Framework“云优先、移动优先”
2013 Update 2正式发布 .NET Framework“云优先.移动优先” 投递人 itwriter 发布于 2014-05-13 12:33 评论(19) 有2155人阅读 原文链接 ...
- javaIO流实现读写txt文件
javaIO流实现文件读写 文件写入: InputStreamReader BufferedReader 文件读取: FileOutputStream package javatest.basic22 ...
- iOS 制作 framework 教程
直接看步骤 废话不多说,哈哈! 1.新建一个静态库工程: 2:取自己喜欢的名字: 3.删除向导所生成工程中的 Target: 3.删除TestFrameWork对应的工程文件夹: 5:删除bulid ...