nhibernate查询与非相关实体的复杂连接

时间:2013-02-14 12:28:05

标签: c# linq nhibernate queryover

所以我花了最后几个小时寻找答案,我似乎找不到任何有意义的东西。

public class Game
{
   public virtual Guid ID { get; set; }
   public virtual ResultStructure Structure { get; set; }
   public virtual List<Result> Results { get; set; }
}

public class Result
{
  public virtual Player Player { get; set; }
  public virtual int Position { get; set; }
}

public class ResultStructure
{
  public virtual Guid ID { get; set; }
  public virtual List<ResultOutcomes> Outcomes { get; set;}
}

public class ResultOutcomes
{
  public virtual int Position { get; set; }
  public virtual int Points { get; set; }
}

public class PlayerSummary
{
  public virtual Player Player { get; set; }
  public virtual int Points { get; set; }
}

我要做的是获取一系列玩家以及他们在众多不同游戏中获得的积分(game以上的多个实体包含游戏列表)。所以查询的最终结果是List<PlayerSummary>我正在寻找的SQL看起来像这样:

SELECT p.*, Sum(rs.points) FROM result r
  JOIN player p on r.playerid = p.id
  JOIN game g on r.gameid = g.id
  JOIN resultstructure rs on g.resultstructureid = rs.id
  JOIN resultoutcomes ro on rs.id = ro.resultstructureid AND ro.position = r.position

注意,我还需要对结构实体进行一些查询/求和,这就是它包含的原因。

我正在尝试使用NHibernate,使用TypeSafe的东西,我的计划是让应用程序与数据库无关,所以我不能使用直接SQL(目前它正在使用Postgres,但我可能会转向SQL服务器在某一点上。)

我并不特别想使用那些使用这些魔术字符串的“HQL”内容,因此我尝试使用Linq或QueryOver / Query。

有人能指出我正确的方向吗?

1 个答案:

答案 0 :(得分:6)

似乎上述情况在我的情况下是可能的,因为存在关系,它只是不直接。

您可以使用JoinAlias

基本区别在于使用JoinAlias,您可以将多个表连接到同一个基表,与JoinQueryOver一样,它只需要通过表格的线性进展,每个表只连接到前一个表。< / p>

所以查询看起来像这样。

Result resultAlias = null;
ResultOutcome outcomeAlias = null;
ResultStructure structureAlias = null;

var results = Session.QueryOver(() => resultAlias) // Assigns resultAlias so it can be used further in the query.
   .Inner.JoinQueryOver(x => x.Game) // returns a QueryOver Game so you can do a where on the game object, or join further up the chain.
   .Inner.JoinAlias(x => x.ResultStructure, () => structureAlias) // joins on the Structure table but returns the QueryOver for the Game, not the structure.
   .Inner.JoinAlias(() => structureAlias.Outcomes, () => outcomeAlias) // same again for the outcomes
   .Where(() => resultAlias.Position == outcomeAlias.Position)
   .Select(
        Projections.Group(() => resultAlias.Player),
        Projections.Sum(() => outcomeAlias.Points)
   );

这应该给人们这个想法。这样做的缺点是对“位置”的限制不会发生在Join上,而是发生在Where子句中。我很高兴听到有人可以选择这样做,因为这会强制数据库查询计划程序沿着特定的路径行进。

仍在进行转换和排序,但这让我更进一步。