Fluent NHibernate - 将属性映射到连接表上的列

时间:2011-03-03 23:51:27

标签: join fluent-nhibernate

我有几张桌子,例如:

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

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

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)连接到Manufacturer表,在Product.ManufacturerId = Manufacturer.Id上,并获取Manufacturer.Name列,在对象上填充ManufacturerName属性。

2 个答案:

答案 0 :(得分:6)

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

  1. 将ManufacturerName属性添加到Product类
  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");
    
  3. 希望这有帮助。

答案 1 :(得分: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");

这会将规范化的制造商名称作为非规范化字段保留在Product表中。该字段也将存在于Manufacturer表中。当您检索JUST产品时,您将从Product表中获取名称。在制造商因某些其他原因(或急切加载)进行延迟初始化后,您将从Manufacturer表中获取名称,这意味着您可以将制造商记录的名称保留在产品中。