2015-06-18 27 views
1

我有一个场景,需要一个映射,需要通过中间表连接到2个表(请参阅示例),目前它是通过公式实现的,该公式可以转换为子查询,但是我想要使用连接来更有效地执行此操作。请帮助通过中间表流畅的NHibernate映射

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

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

小记,我期待的是,在问题的公式片断仅仅是一个例子,因为A.Id = B.Id = C.Id意味着不需要乙...

所以我们要介绍的实体:

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获得与标准查询相同的结果。

在情况下,在

  • 我们想减少链和
  • 我们知道该公式的内容始终只读 ...

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

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将代表DB侧的视图。如果我们不能引入视图,我们可以将其定义为内联SELECT

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

A.Id和C.Id是不一样的。你的假设是正确的 – Ahsan