【问题标题】:Filtering and projecting an association using NHibernate QueryOver使用 NHibernate QueryOver 过滤和投影关联
【发布时间】:2011-09-01 12:21:42
【问题描述】:

假设你有一个类似这样的实体:

public class Mailinglist
{
    public virtual Guid Id { get; set; }
    public virtual ICollection<Subscriber> Subscribers { get; set; }
}

实体的 NHibernate 映射如您所料:Id 是标识符,Subscribers 映射到 &lt;set&gt;&lt;many-to-many&gt; 引用 Subscriber 实体。

现在,我有一个Mailinglist 的实例,需要获取与Subscriber 属性上的某个过滤器匹配的前100 个订阅者的列表。由于性能限制和数据库中的数据量,myMailinglist.Subscribers.Where().Take() 不是一个选项。因此,我正在尝试对 NHibernate 进行查询,它将仅从数据库中获取 100 个 Subscriber 实例。

我最初的尝试(没有任何过滤)是这样的:

var subscribers = session
    .QueryOver<Mailinglist>()
    .Where(m => m.Id == myMailinglistId)
    .JoinQueryOver(m => m.Subscribers)
    .Take(100)
    .List();

这显然是不对的,因为我得到的列表包含 100 条对 Mailinglist 的引用,我已经知道了。生成的 SQL 看起来不错,但让我认为我只需要显式添加投影/转换。

我一直在尝试查找一些相关文档来帮助我,但似乎找不到任何解决此类查询的内容。有人可以提示我吗?

【问题讨论】:

  • 订阅者没有邮件列表的 FK?为什么你不能只做一个 QueryOver.Where(s => s.MailingListId == myMailinglistId and ...).Take(100).List(); ?
  • 订阅者是否有对邮件列表的反向引用?
  • SubscriberMailinglist 之间的关系是多对多的。目前,Subscriber 没有任何反向引用,但我认为在其上添加 Mailinglists 集合属性没有任何问题。

标签: nhibernate queryover


【解决方案1】:
var subquery = QueryOver.Of<Mailinglist>()
    .Where(m => m.Id == myMailinglistId)
    .JoinQueryOver(m => m.Subscribers, () => subscriber)
    .Select(m => subscriber.Id);

var subscribers = session.QueryOver<Subscriber>()
    .WithSubquery.WhereProperty(s => s.Id).In(subquery)
    .Take(100)
    .List();

【讨论】:

    【解决方案2】:

    HQL 不是更容易阅读吗?

    还没有测试,但在以下几行:

    Query query = 
     session.createQuery("from Mailinglist m where m.subscriber = :code ")
    .SetMaxResults(100)
    .setParameter("code", "%john%");
    List list = query.list();
    

    setMaxResults 应该转换为 T-SQL“选择前 100 个...”

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2015-01-02
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2014-05-08
      • 1970-01-01
      相关资源
      最近更新 更多