【问题标题】:How do I retrieve a list of base class objects without joins using NHibernate ICriteria?如何使用 NHibernate ICriteria 检索没有连接的基类对象列表?
【发布时间】:2009-12-10 21:43:14
【问题描述】:

假设我有一个名为 Pet 的基类和两个继承 Pet 的子类 Cat 和 Dog。

我只是将它们映射到三个表 Pet、Cat 和 Dog,其中 Pet 表包含基类属性,Cat 和 Dog 表包含 Pet 表的外键以及特定于猫或狗的任何其他属性。加入子类策略。

现在,使用 NHibernate 和 ICriteria,我怎样才能获得所有不同宠物的列表作为 Pet 对象,不是 Cat 或 Dog 对象 - 只是普通的 Pet 对象,而不与另一个进行任何连接表?我只对 Pet 中包含的信息感兴趣。

【问题讨论】:

  • 我不得不求助于原生 SQL 来让这个工作。但这给了我很多代码来动态构建查询字符串,例如基于过滤器。必须有一种方法可以仅使用 ICriteria 来做到这一点。 Ayende 一定有想过,对吧?
  • 我很好奇这是否可以用 HQL 完成——这篇文章 (randomcode.net.nz/2008/09/19/…) 表明它可以,但您的情况不同,因为您将结果限制为基类类型。跨度>

标签: nhibernate icriteria


【解决方案1】:

我刚刚做了类似的事情,发现 Ayende 的 blog post 非常有帮助!我采用了加入子类的方法,它很好地支持查询基类。

但是,要在不加入的情况下找到“唯一的宠物”,我认为您需要使用每类表的层次结构方法。或者,您可以使用每个子类的表,只对子类进行左连接,并将其限制为在任何左连接上都没有匹配的行。

【讨论】:

  • 那是 Ayende 的一篇很棒的帖子。我发现联合子类策略很有趣,我必须研究一下。我想知道如果我想要来自 7 个联合表的前 10 个结果,性能会受到什么影响......
【解决方案2】:

嗯,我认为选择“作为宠物”会带回所有对象(不仅仅是未分类的宠物)。我不知道这样做的干净方法,但我不是 NH 专家。

也许您可以直接查询父表中的鉴别器列?虽然您可能不得不使用自定义 SQL 查询而不是 HQL 或 ICriteria。

【讨论】:

    【解决方案3】:

    这似乎工作正常:

    我创建了一个视图,它选择了 Pet 表上的所有列。然后,我创建了一个映射到视图的简单 DTO 类。之后就可以使用ICriteria了。

    也许不是最漂亮或最干净的解决方案,但肯定比动态查询字符串更容易使用。

    【讨论】:

      【解决方案4】:

      我不相信您可以使用 Criteria API 做到这一点。但是,您可以使用 HQL:

      var hql = @"from Pet p where p.class = Pet";
      

      【讨论】:

      • 这将加入所有地方。它不会将猫或狗作为宠物归还,只会归还那些只是宠物的。也许我有点不清楚我想要所有种类的宠物,但只想要 Pet 类包含的信息。
      • 这就是您所要求的:“不是 Cat 或 Dog 对象 - 只是普通的 Pet 对象”,我不希望这会产生任何连接。如果您真正想要的是将 Cat 或 Dog 对象“强制”为 Pet 对象,那么您必须自己做。这是一种非面向对象的方法,我不希望(或不希望)NH 支持它。
      【解决方案5】:

      为什么不为“PetsOnly”创建一个新地图并删除您的鉴别器和其他非必填字段?我认为上面的克里斯托弗暗示了同样的事情。仍应为您提供完整的插入更新和删除选择支持。宠物只是一个Pet...

      【讨论】:

        【解决方案6】:

        对于许多情况来说已经足够了:将属性投影到对象本身中。

        请小心使用,因为对象已损坏,因为它的类型不正确

        var propsToSelect = Projections.ProjectionList();
        foreach (var prop in sessionfactory.GetClassMetadata(typeof(Pet)).PropertyNames)
        {
            propsToSelect.Add(Projections.Property(prop.Name), prop.Name);
        }
        var results = session.CreateCriteria<Pet>()
            .SetProjection(propsToSelect)
            .SetResultTransformer(Transformers.AliasToBean<Pet>())
            .List<Pet>();
        

        【讨论】:

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