【问题标题】:NHibernate - AddEntity and AddJoin problemNHibernate - AddEntity 和 AddJoin 问题
【发布时间】:2013-06-12 19:29:35
【问题描述】:

我正在使用带有 SQL 查询的 NHibernate 来填充一些实体对象。

我有一个 Item 对象,它引用了一个 User 对象(表示 Item 的所有者)

class Item
{
public User User;
}

我的 SQL 查询是(它实际上更复杂,这就是为什么我不能使用 HQL,但我从这个开始是为了确保 AddJoin/AddEntity 工作正常):

SELECT {i.*}, {u.*}
FROM Item i INNER JOIN User u ON (i.UserId = u.Id)
WHere i.Id = 5

这是我的代码:

var x = session.CreateSQLQuery(sql)
    .AddEntity("i", typeof(Item))
    .AddJoin("u", "i.User")
    .List();

当我运行它时,我得到一个二维数组。数组中的每个项目都包含一个 Item 对象(已初始化 User 属性)和 User 对象本身。

我错过了什么?我希望获得一个初始化了 User 属性的 Item 对象列表(这是我解释文档的方式)。

【问题讨论】:

    标签: nhibernate


    【解决方案1】:

    我只是浪费了一个下午来解决这个问题。 SetResultTransformer(CriteriaUtil.DistinctRootEntity) 对最后添加的东西进行操作。

    这是我从查询中获取第一个实体的操作。不过有一个问题,我不得不将 NHibernate.DistinctRootEntityResultTransformer.TransformTuple() 修改为虚拟的。对我们来说没什么大不了的,因为我们已经为 NHibernate 分支了一些像这样的琐碎添加。如果您不想分支 NH,则可以轻松滚动自己的 IResultTransformer,确保项目是唯一的。

    将此添加到您的查询中:

    query.SetResultTransformer(new FirstTupleDistinctResultTransformer());
    

    这是新课程:

    public class FirstTupleDistinctResultTransformer : DistinctRootEntityResultTransformer
    {
        public override object TransformTuple(object[] tuple, string[] aliases)
        {
            return tuple[0];
        }
    } 
    

    【讨论】:

      【解决方案2】:
      var x = session.CreateSQLQuery(sql)     
          .AddEntity("i", typeof(Item))     
          .AddJoin("u", "i.User") 
          .AddEntity("i", typeof(Item)).setResultTransformer(Criteria.DISTINCT_ROOT_ENTITY);
      

      它只会返回项目

      【讨论】:

        【解决方案3】:

        已经有一段时间了,但我认为你错过了这个:

        .SetResultTransformer(new DistinctEntityRootTransformer())
        

        【讨论】:

        • 谢谢本。我添加了这个 - .SetResultTransformer(new DistinctRootEntityResultTransformer()) - 但后来我得到了一个用户列表,而不是所需的项目列表。我认为根实体是项目,所以肯定有其他问题。
        • 当有另一个 addjoin 时这不起作用。您需要滚动自己的 DistinctRootEntityResultTransformer。见下文。
        【解决方案4】:

        试试这个

            using NHibernate.Transform;
            //..
        
            var x = session.CreateSQLQuery(sql)     
            .AddEntity("i", typeof(Item))     
            .AddJoin("u", "i.User") 
            .AddEntity("i", typeof(Item))
            .SetResultTransformer(new DistinctRootEntityResultTransformer())
        
            .List(); 
        

        【讨论】:

          【解决方案5】:

          如果省略 AddJoin 方法会发生什么? 仅仅指定 AddEntity 还不够吗?

          【讨论】:

            【解决方案6】:

            如果你的映射是正确的,你可以像这样使用 join fetch 来获得这一切:

            var x = session.CreateQuery("from Item i join fetch i.User").List<Item>();
            

            【讨论】:

            • 谢谢大卫,但实际的 SQL 比我包含的要复杂得多。我需要了解为什么基本 SQL 没有返回我期望的结果,因为我不能将 HQL 用于最终解决方案。
            猜你喜欢
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 2011-01-23
            • 1970-01-01
            • 2010-11-17
            • 2011-06-04
            • 2016-09-05
            相关资源
            最近更新 更多