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 ************************************************************** ...
随机推荐
- 图文解说PhpStorm 7.0版本语法着色
前不久,我们测试了PhpStorm7.0版本对PHP 5.5的支持,今天我们将继续对PhpStorm 7.0版本对代码支持进行测试. 我们知道,在PhpStorm 6.0版本中,提供一个黑色背景的代码 ...
- easyui datagrid显示进度条控制操作
在当我们需要控制时间前台实际项目页面datagrid显示进度条的数据加载时运行,和datagrid默认情况下只在有url加载运行时的数据显示方式的进度条.下面的代码手动控制: 打开一个进度条: $(' ...
- BackgroundWorker组件使用总结
首先在窗体拖入一个BackgroundWorker组件,根据功能需要设置BackgroundWorker的属性 WorkerSupportsCancellation = true; 允许取消后台正在执 ...
- Android在包名称更改项目
通常时引起包名称的变化R文件错误,有时原因不明Manifest混乱多个文本文件. 所以,我们现在感到最简单方便的包名称变更流程文件,如以下: 如果程序包命名com.pepper.util,我们将更改包 ...
- 六白话经典算法系列 高速分拣 高速GET
高速分拣,因为相同的排序效率O(N*logN)几个订购流程更高效,因此,经常使用,再加上高速分拣思想----分而治之的方法也是非常有用的,如此多的软件公司书面采访.它包含了腾讯,微软等知名IT企业宁 ...
- CTP API开发期货自动交易平台概论
题目比较小众,先介绍一下CTP. 综合交易平台CTP(Comprehensive Transaction Platform)是由上海期货信息技术有限公司(上海期货交易所的全资子公司)开发的期货交易平台 ...
- String的使用
String的常用方法 方法 说明 Anchor() 创建html锚 Concat() 把字符串连接起来 indexOf() 查找字符出现的位置 lastIndexOf() 查找最后出现字符 char ...
- WCF RIA Services异常
.svc处理程序映射缺失导致的WCF RIA Services异常 在确定代码.编译结果和数据库都正常的情况下,无法从数据库取到数据.错误提示:Sysyem.Net.WebException:远程服务 ...
- Javascript技巧实例精选(4)—FTP网站登录的Javascript实现
FTP网站登录的Javascript实现 >>点击这里下载完整html源码<< 这是最后的截图 这是核心Javascript源码 function goFtpSite() { ...
- C# 学习笔记1 .NET平台,C#的重要概念
.NET平台构成的三个关键实体是: 1.CLR(公共语言运行库):为我们定位,加载,管理.NET类型,同时负责一些底层细节的工作,如内存管理,应用托管,处理线程,安全检查等,它包含了一个重要名为msc ...