2011-04-26 122 views
0

我有一个用户实体具有IList属性。对于 这个映射是这样的:流利NHibernate和多个关键列

 HasMany(x => x.Forms) 
      .Cascade.None() 
      .AsBag().KeyColumn("Supervisor") 
      .Key(key => key.Not.Update()) 
      .PropertyRef("Email"); 

现在我在一个新的功能要求基本上是增加了一个 KeyColumn应该也将填充到这个属性。实质上, 每个表格可以有一个“主管”和一个“备用”,我需要这个 属性来填充任何表格,其中User.Email等于 (表格BELONG到用户如果是User.Email == Form.Supervisor OR User.Email == Form.Alternate)。

有没有办法做到这一点?只需通过 增加另一个KeyColumn 规范简单地覆盖了前一个,并添加键Keys()方法似乎不允许多个键列像我 想......我正在寻找一种方式基本上告诉它这个 关系应该找到一个WHERE Superviser = Email OR Alternate = Email,但它似乎并不支持OR子句...

我的其他选项基本上重复此映射,但对于另一个属性中的“替代”,然后猛然收集在一起我的消费代码,但我想看看NHibernate是否足够聪明,这是可能的...

有何建议?

回答

1

据我所知,不 - NHibernate不支持这种不寻常的连接类型。我会像你说的那样完全接近你。使用两个集合 - User.SupervisorFormsUser.AlternateForms,然后再合并它们,也许使用LINQ的Concat方法来做到这一点。你可以定义属性为你做这个串联:

public virtual IEnumerable<Form> Forms 
{ 
    get { return SupervisorForms.Concat(AlternateForms); } 
} 

如果要加载一个完全初始化Forms集合User在一个往返到数据库中,那么你可以使用这种方法从NHibernate的文档Improving Performace - Multi Query部分:

User user = s.CreateMultiQuery() 
    .Add("select u from User u left join fetch u.SupervisorForms where u.Id = :id") 
    .Add("select u from User u left join fetch u.AlternateForms where u.Id = :id") 
    .SetInt32("id", 123) 
    .UniqueResult<User>(); 

该代码使用CreateMultiQuery()和HQL - 但是这种方法应该与您选择的查询配料语法的工作一样:CreateMultiQuery()CreateMultiCriteria()Future()/FutureValue()

+0

这正是我最终做的事情,因为我在NHibernate基地周围扯皮没有任何回报。违反了我希望尽可能限制SQL命中的条件(这基本上使它们翻倍),但是它的工作原理并没有受到巨大的性能影响。 – 2011-04-28 04:07:24

+0

增加了有关在数据库中往返一次的情况下预加载这两个集合的信息。注意 - NHForge目前似乎处于关闭状态,因此链接被破坏,但Google有一个[缓存的页面副本](http://webcache.googleusercontent.com/search?q=cache:JC6X0f6JGfoJ:www.nhforge .ORG/DOC/NH/EN/index.html中+ nhforge +文档和CD = 1&HL = EN&CT = clnk&GL = US&客户=火狐-A&源= www.google.com)。 – 2011-04-28 15:31:13