流畅的NHibernate映射通过中间表

时间:2015-06-18 03:13:15

标签: c# nhibernate fluent-nhibernate

我有一个场景,需要通过中间表连接到2个表的映射(参见示例),目前通过转换为子查询的公式实现,但我想使用连接更有效地做到这一点。请帮忙

  Map(x => x.PropertyX).Formula(@"
               (SELECT C.ColumnX
                FROM   TableA A 
                       JOIN TableB B
                         ON A.Id = B.Id 
                       JOIN TableC C
                         ON C.Id = B.Id 
                WHERE  A.ColumnY = 898)");

1 个答案:

答案 0 :(得分:1)

您使用过的解决方案可以转换为标准的ORM用例。这里面向本机或面向对象/实体的解决方案是引入many-to-oneone-to-many映射。这将带来很多好处(懒惰加载==仅在需要时查询......)

小记,我希望问题中的FORMULA片段只是一个例子,因为A.Id = B.Id = C.Id意味着不需要B ...... < / p>

所以我们应该引入实体:

public class A
{
    public virtual B B { get; set; }
}
public class B
{
    public virtual IList<A> As { get; set; }  // not needed
    public virtual C C { get; set; }
}
public class C
{
    public virtual IList<B> Bs { get; set; }  // not needed
    public virtual string ColumnY { get; set; }
}

及其映射:

public AMap()
{
    References(x => x.B);
}
public BMap()
{
    References(x => x.C);
    HasMany(x => x.As);   // not needed
}
public CMap()
{
    HasMany(x => x.Bs);   // not needed
    Map(x => x.ColumnY);
}

现在我们可以使用少量JOIN的标准查询获得相同的结果。

万一,那个

  • 我们希望减少该链和
  • 我们知道,FORMULA内容始终只读 ......

我们可以创建一个虚拟实体 - 映射到视图:

public class A
{
    public virtual BView BView { get; set; }
}
public class BView
{
    public virtual string ColumnY { get; set; }
}

public AMap()
{
    References(x => x.BView)
}
public BMap()
{
    Table("viewName");
}

viewName表示数据库端的视图。如果我们不能引入视图,我们可以将其定义为内联SELECT

public BMap()
{
    Subselect(@"
        SELECT B.col1 as COL1,
               C.col2 as COL2,
               ..
        FROM B
         LEFT JOIN C
          ON B.CId = C.Id
        ");
}