【问题标题】:NHibernate QueryOver Select only needed modelNHibernate QueryOver 只选择需要的模型
【发布时间】:2011-07-28 14:02:52
【问题描述】:

我在 QueryOver 中仅选择所需模型时遇到了一点问题。 这是我的场景

 var qOver = _HibSession.QueryOver<ModelA>(() => Ma)
                .JoinAlias(() => Ma.MbList, () => Mb, JoinType.LeftOuterJoin)
                    .Where(() => Mb.ID == _MbId)
                .JoinAlias(() => Mb.McList, () => Mc,JoinType.LeftOuterJoin)                    
                    .Where(() => Mc.ID == _McId)
                .JoinAlias(() => Mc.MdList, () => Md, JoinType.LeftOuterJoin)
                    .Where(() => Md.ID == _MdID)                                             
                .OrderByAlias(() => Ma.ID).Asc
                .Take(iTake)
                .Skip(iSkip)
                .Future<ModelA>();

前面的代码生成如下SQL

SELECT TOP n Ma.*,Mb.*,Mc.*,Md.*
FROM Ma 
LEFT JOIN Mb ON (...conditions...)
LEFT JOIN Mc ON (...conditions...)
LEFT JOIN Md ON (...conditions...)
WHERE Mb.ID = _MbId
AND Mc.ID = _McId
AND Md.ID = _MdId
ORDER BY Ma.ID ASC

问题是 Mc 和 Md 表重复了我的结果。所以我的 SELECT 语句中只有 Ma 和 Mb。

SELECT TOP n Ma.*,Mb.*
FROM
.
.
.

我怎样才能达到这个结果? 谢谢!

【问题讨论】:

    标签: c# nhibernate queryover


    【解决方案1】:

    尝试使用Fetch 而不是JoinAlias。像这样的东西应该可以完成这项工作:

    ... .QueryOver<Ma>().Fetch(ma => ma.MbList).Eager
    

    并且不要在您的映射中使用fetch="join"

    当您强制 NHibernate 使用 join 时,它将返回与您的表的笛卡尔积中的行数一样多的行。由于每个 ModelA 对象只需要一个列表项,因此您必须让 NHibernate 使用简单的 select 语句而不是 join

    【讨论】:

    • Fetch 模式允许我只将 ModelA “加入”到其他模型,但我需要将 ModelA “加入”到 ModelB、ModelB 到 ModelC 和 ModelC 到 ModelD;我怎样才能达到那个结果,或者我怎样才能使用带别名的提取模式?谢谢!!
    【解决方案2】:

    您需要通知 NHibernate 不要重复根实体 (ModelA)。您可以使用以下语句执行此操作:

    .TransformUsing(Transformers.DistinctRootEntity)
    

    【讨论】:

    • 我在发布之前尝试过这个语句,但它不起作用,因为我有一个 Take 语句,并且 TrasformUsing 是在 Take 语句之后应用的,所以我的行数少于 nTake
    【解决方案3】:

    似乎唯一的方法是使用主要的 QueryOver 选择主模型和过滤的子查询

    我的意思是这样的

    var qOverInclude = QueryOver.Of<MyModel>(() => mModel)
                    .JoinAlias(() => mModel.MyList, () => mList, JoinType.LeftOuterJoin)
                        .Where(() => mList.ID == myID)
                        .And(() => mList.Type == myType)
                    .Select(x => x.IdMyModel);
    
      var qOver = _HibSession.QueryOver<MyModel>(() => mModel)
                    .JoinAlias(() => mModel.MyDescription, () => mDescription, JoinType.LeftOuterJoin)
                    .Where(() => mDescription.IDLanguage == myLanguage)
                    .WithSubquery.WhereProperty(() => mModel.IdMyModel).In(qOverSubQuery)
                    .OrderByAlias(() => mModel.IdMyModel).Asc
                    .Future<MyModel>();
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多