使用 Fluent NHibernate 和 AsList() 时指定主键
Posted
技术标签:
【中文标题】使用 Fluent NHibernate 和 AsList() 时指定主键【英文标题】:Specifying the Primary Key when using Fluent NHibernate and AsList() 【发布时间】:2012-12-11 16:38:01 【问题描述】:我有一个场景,其中一个用户实体有一个国家 ID 列表,保存为 IList。
public virtual IList<int> TradeCountries get; protected set;
目前这被映射为
HasMany(x => x.TradeCountries).Element("TradeCountryId").AsList(x => x.Column("TradeCountryIndex"));
结果表是这样定义的
create table TradeCountries (
User_id INT not null,
TradeCountryId INT null,
TradeCountryIndex INT not null,
primary key (User_id, TradeCountryIndex)
)
这一切都很好 - 但是我想让 TradeCountries 上的 PK 成为 User_id,TradeCountryId。使用 AsList() 进行映射时,我似乎找不到这样做的方法。有什么想法吗?
【问题讨论】:
您希望您的主键包含两个字段吗? (User_id 和 TradeCounryId) PK为什么要TradeCountryId?唯一性约束? NHibernate 在 PK 中使用索引,因为这对 NH 很重要。你真的需要在集合中存储每个国家的位置吗? @OskarBerggren 我想将其映射为一个列表,只是为了避免我在将组件映射为集合或包时遇到的“全部删除/重新插入”行为 嗯...我不希望您使用集合获得 delete-all-reinsert - 因为元素是唯一的,所以所有者引用和元素值/id 形成一个唯一键,它启用针对单个行。要启用此功能,您必须为元素指定 not-null="true",但不幸的是,文档中似乎缺少此功能,并且未在 Fluent NHibernate 中公开(尽管添加它可能相当容易)。无论如何,还有idbag可以防止此类问题。 【参考方案1】:Fluent NHibernate 中使用的集合的转换是这样进行(as described here) 的:
// <set>
public virtual ISet<Child> Children get; set;
HasMany(x => x.Children); // <set />
// <bag>
public virtual IList<Child> Children get; set;
HasMany(x => x.Children); // <bag />
// <list>
public virtual IList<Child> Children get; set;
HasMany(x => x.Children).AsList(...; // <list />
这些映射的本质/区别在文档Understanding Collection performance 和Ayende's post: <list>
) 中有详细描述。 提取:
...虽然
<set/>
是一个无序集合,具有独特元素,但<list/>
是顺序很重要的元素的集合,并且重复 允许元素...
换句话说,当使用<list>
时,您必须在 key 和 index 列上保留 PK,因为可能存在重复。
在您的情况下,仅<bag>
映射(没有明确的.AsList()
调用)就足够高效了,您可以删除索引列,并将PK 移动到 key 和 element (User_id, TradeCountryId)。
注意:C# IList 仍然允许有更多“相同”的元素,你应该在业务层检查它
【讨论】:
以上是关于使用 Fluent NHibernate 和 AsList() 时指定主键的主要内容,如果未能解决你的问题,请参考以下文章
如何使用 Fluent-NHibernate 和 MySQL 指定自动递增 (int) 标识列
如何使用 Fluent 设置 NHibernate.Burrow?
NHibernate 2 + Fluent Nhibernate 中等信任
使用 Fluent NHibernate 和 AsList() 时指定主键
Fluent NHibernate使用我的用户名作为前缀创建表
Castle Windsor 3 + Fluent NHibernate + Castle.NHibernate.Integration