流利的NHibernate加入约束

时间:2009-11-30 16:45:29

标签: c# nhibernate fluent-nhibernate nhibernate-mapping

我有一个实体,其特性分布在两个表格中,我想使用Fluent NHibernate映射到一个类,但是在连接表上有约束。

我已经将我的问题的领域改为熟悉的“客户”域名,所以我的例子可能有点人为,但它说明了我的问题。这是基本的;我有一个Customer表,其中包含一些客户属性,但客户的名字和姓氏都保存在一个单独的CustomerName表中,作为链接到客户的两行,并标识为名字和姓氏。

以下是表架构:

CREATE TABLE客户(     CustomerId int,     生日日期 )

CREATE TABLE CustomerName(     CustomerId int NOT NULL,     CustomerNameTypeId int NOT NULL,     名称nvarchar(25)NOT NULL )

CREATE TABLE CustomerNameTypes(     CustomerNameTypeId NOT NULL,     描述nvarchar(25)NOT NULL )

,CustomerNameTypes表包含两行: 1,“FirstName” 2,“SecondName”

我需要的是一个Fluent Mapping,它将上面的内容映射到以下内容:

public class Customer
{
    public virtual int CustomerId { get; set; }
    public virtual string FirstName { get; set; }
    public virtual string LastName { get; set; }
    public virtual DateTime Birthday { get; set; }
}

任何人都可以帮忙吗?!

非常感谢提前 克里斯布朗

3 个答案:

答案 0 :(得分:1)

无法用nHibernate真正回答这个问题,但我还有其他几个可以帮助你解决它的选项!

  1. 我个人会按如下方式重写sql:

    select 
          c.CustomerId, 
          c.Birthday, 
          fn.Name, 
          ln.Name
    from Customer c
    left join CustomerName fn on c.CustomerId = fn.CustomerId
    left join CustomerNameTypes fnt on fnt.CustomerNameTypeId = fn.CustomerNameTypeId
          and fnt.[Description] = 'First'
    left join CustomerName ln on c.CustomerId = ln.CustomerId 
    left join CustomerNameTypes lnt on lnt.CustomerNameTypeId = ln.CustomerNameTypeId
          and lnt.[Description] = 'Last'
    

    这可能有助于您在使用NHibernate时解决。

  2. 另一种选择是使用视图。我个人使用LLBLGenPro,在Linq在v2.6中可用之前,这是我最喜欢的方法,可以快速轻松地解决硬查询。

  3. 这将是我想象中的一个难题,特别是如果你有一个顽固的DBA或者它是第三方数据库!取消规范化数据库。这种结构太过标准化,这是你遇到这个问题的全部原因。

  4. 无论如何,我知道这不是你问题的答案,但我希望你会得到一些用处! :)

答案 1 :(得分:1)

我知道这并没有完全回答你的要求,但......

如果LastName和FirstName都位于CustomerName表的同一行(但它们不是),则可以使用< join>完成此操作。映射。 Ayende describes this HBM mapping在他的博客上。这里有一个流利的nhibernate示例:Entity spanning multiple tables。从那时起,方法名称已从WithTable()更改为Join()。这就是它的样子:

public class CustomerMap : ClassMap<Customer>
{
    public CustomerMap()
    {
        Id(x => x.CustomerId);
        Join("CustomerName", m =>
        {
            m.Map(x => x.FirstName);
            m.Map(x => x.LastName);
        });
        // ... other properties ...
    }
}

我不确定如何解决两个名字在不同行上的问题。

答案 2 :(得分:0)

我想补充一下,这是等价的sql:

select c.CustomerId, c.Birthday, fn.Name, ln.Name
from Customer c
  left join CustomerName fn on c.CustomerId = fn.CustomerId and fn.CustomerNameTypeId = (select CustomerNameTypeId from CustomerNameTypes where Description = 'First')
  left join CustomerName ln on c.CustomerId = ln.CustomerId and ln.CustomerNameTypeId = (select CustomerNameTypeId from CustomerNameTypes where Description = 'Last')

喝彩!