2011-03-03 56 views
4

我有一个情侣表,例如:功能NHibernate - 映射一个属性栏上的连接表

  • 产品{ID,名称,ManufacturerId,...}
  • 制造商{ Id,Name,...}

我希望能够在我的Product对象中包含ManufacturerName(而不必在我只需要名称时加载整个Manufacturer行)。我的产品地图看起来像...

Table("Product"); 
Id(x => x.Id, "Id"); 
Map(x => x.ProductName, "ProductName"); 
Map(x => x.ManufacturerId, "ManufacturerId"); 
References(x => x.Manufacturer, "ManufacturerId"); 

我需要添加什么来填充我的Product对象的ManufacturerName属性?我相信我需要进行某种Join()调用,但我无法弄清楚如何使用所有相关参数编写它。它需要将当前表(产品)加入到制造商表中,在Product.ManufacturerId = Manufacturer.Id上,并抓住Manufacturer.Name列,在对象上填充ManufacturerName属性。

回答

5

我想你可以使用formula动态检索制造商名称。这不是一个优雅的解决方案,我个人更喜欢使用一个单独的sql视图映射到一个新的实体(例如ProductExtra等),在那里它只会​​查询必要的列,但无论如何。在这里,我们去:

  1. 的ManufacturerName属性添加到产品类
  2. 添加映射线为新的属性您ProductMap:

    Table("Product"); 
    Id(x => x.Id, "Id"); 
    Map(x => x.ProductName, "ProductName"); 
    Map(x => x.ManufacturerId, "ManufacturerId"); 
    Map(x => x.ManufacturerName).Formula("(select m.ManufacturerName from Manufacturer m where m.Id = ManufacturerId)"); 
    
    References(x => x.Manufacturer, "ManufacturerId"); 
    

希望这有助于。

+0

这看起来像是一个很好的解决方案,除了DB是一个不支持select参数内的子查询的oracle版本。 (呃)虽然 –

+0

非常感谢您接受这个答案,因为它可能适用于后来寻找答案的99%的人。可悲的是,我在使用8年前的Oracle数据库的1%中,这不起作用。 –

+0

啊..是的,我在Oracle 9中测试,所以这可能是为什么它在那里工作。那么,你仍然可以使用一个辅助sql视图并将其映射到一个新的实体,该实体只包含一列的子集,然后使用它来代替常规产品,但我想它主要取决于场景。 –

1

NH连接非常棘手,并且需要您的模式可能不支持的事情。例如,连接表的主键与当前表的主键相匹配。它很像OneToOne映射,除了NH不会为此产生明确的约束。由于在你的映射中情况并非如此(看起来像是多对一的引用),我怀疑你可以做一个明确的连接工作。

尝试映射“直通”属性:

public class Product 
{ 
    ... 

    public string ManufacturerName 
    { 
     get{return NHibernateUtil.IsInitialized(Manufacturer) 
        ? Manufacturer.Name : manufacturerName;} 
     set{if(NHibernateUtil.IsInitialized(Manufacturer)) 
      Manufacturer.Name = value 
      else 
      manufacturerName = value;} 
    } 
} 

... 

//In your mapping: 
Map(x => x.ManufacturerName, "ManufacturerName"); 

这将坚持规范化制造商的名称到产品表作为一个非标准化的领域。该字段也将存在于制造商表格中。当您检索产品时,您从产品表中获取名称。制造商由于某种其他原因(或急切加载)而被延迟初始化后,您会从制造商表中获得该名称,这意味着您可以将制造商记录的名称保存到产品中。

+0

是的,这是多对一的。但是产品表实际上并没有ManufacturerName,所以在制造商行初始化之前它会一直是空白的(或者只是在映射时会抛出一个错误)? –

+0

您必须将该字段添加到表中,或从可编辑视图中提取产品记录。这是ORM的缺点; NH只是希望你足够的了解你已经映射的内容,当你要求它提供一条记录时,将其全部拉回来,并且除了完全定制的查询之外,并没有给你许多选项来将连接的多表结果集从DB。 – KeithS

+0

不幸的是,以任何方式修改数据库都是不可能的。看起来我必须处理每次单独抓取整行的性能,或者处理过多的任何地方,建立一个我需要的所有ManufacturerIds的列表,并从中获取所有ManufacturerId的名称批量。感谢您的帮助。 –