Nhibernate使用联合主键十分复杂(个人觉得!),而且偶师兄也强烈反对使用联合主键。
联合主键实际上也不适合我的需要(只是不知道乱78找,看到了这个东西,觉得可以在当前项目上,就研究了一下。)
其实一开始对这个概念也挺模糊的,找了一大堆资料之后,总结如下(如有错误请指正)
联合主键是把一个表的主键和外键(或其他任意2个或2个以上的键作为联合主键,当然需要符合主键的约束。)就是生成新的主键(概念上),作为引索。
主要适用于多用户的文件管理。(例如简单的网络硬盘)
id为表主键,username用户名要进行约束(避免重复),FileName为上传的用户自定义文件名,每个用户自己的文件名是不能重复的。
这样的结构
表1:user表
id(PK_key/FK) | username(U) |
1 | aaa |
2 | bbb |
表2:file表
id(PK_key) | u_id(U) | FileName |
1 | 1 | test.jpg |
2 | 1 | abc.jpg |
以上的数据是合理的,而且无违反任何约束。
然而数据如果是这样:
id(PK_key/FK) | username(U) |
1 | aaa |
2 | bbb |
id(PK_key) | u_id(U) | FileName |
1 | 1 | test.jpg |
2 | 2 | test.jpg |
这样子就不能对FileName做单一约束。
解决方案有两种:1联合主键联合u_id和FileName。
2用多键约束。
由于联合主键在Nhibernate上实在难用,也不好用。要生成一个新的实体类。而且操作复杂。感觉上很无谓。而且Nhibernate也不推荐。Nhibernate的定义如下:
<composite-id name="propertyName"(1) class="ClassName"(2) unsaved-value="any|none"(3) access="field|property|nosetter|ClassName"> <key-property name="propertyName" type="typename" column="column_name"/> <key-many-to-one name="propertyName class="ClassName" column="column_name"/> ...... </composite-id>
如果表使用联合主键,你可以把类的多个属性组合成为标识符属性。<composite-id>
元素接受<key-property>
属性映射和<key-many-to-one>
属性映射作为子元素。
<composite-id> <key-property name="medicareNumber"/> <key-property name="dependent"/> </composite-id>
你的持久化类必须重载Equals()
和HashCode()
方法,来实现组合的标识符判断等价.也必须实现Serializable
接口
不幸的是,这种组合关键字的方法意味着一个持久化类是它自己的标识。除了对象自己之外,没有什么方便的“把手”可用。你必须自己初始化持久化类的实例,在使用组合关键字Load()
持久化状态之前,必须填充他的联合属性。我们会在TODO:LINKTOCOMPENENTS中说明一种更加方便的方法,把联合标识实现为一个独立的类,下面描述的属性只对这种备用方法有效:
(1) |
|
(2) |
|
(3) |
|
(载自http://www.cnblogs.com/renrenqq)
调试得我发飙~
最后还是使用了多键约束,简单方便。由sql自己去判断。
建立了u_id和FileName联合约束,就解决了这个问题:)。