【问题标题】:Finding the row with matching relations using HQL使用 HQL 查找具有匹配关系的行
【发布时间】:2010-09-28 01:37:19
【问题描述】:

我正在使用 Castle ActiveRecord 和 NHibernate。

我有一个 Instance 类,它与 Component 类具有多对多关系。我想找到与一组特定组件相关的实例。这在 HQL(或 NHibernate 中的其他任何东西)中是否可行?

这个函数的 linq 版本是:

public Instance find(IEnumerable<Component> passed_components)
{
    return Instance.Queryable.Single(i => passed_components.All(x => i.Components.Contains(x)));
}

NHibernate linq 实现当然不能处理这个问题。

我可以编写 HQL 来为其中一个组件执行此操作:

Instance.FindOne(new DetachedQuery("from Instance i where :comp in elements(i.Components)").SetParameter("comp", passed_components.First()));

但是看起来in只比较一个项目和一个集合,它不能比较一个集合和一个集合。

编辑:

这是我能做的最好的:

IQueryable<Instance> q = Queryable;
foreach(var c in components) {
    q = q.Where(i => i.Components.Contains(c));
}

但这是非常低效的。它为每个 where 子句添加一个子选择到 SQL 查询中。一个不必要的长子选择。它连接实例表、实例/组件连接表和组件表。它只需要实例/组件连接表。

由于我的数据的性质,我将实施一个混合解决方案。缩小查询中的实例,然后在必要时使用 linq to 对象来获取正确的实例。 代码如下所示:

IQueryable<Instance> q = Queryable;
foreach(var c in components.Take(2)) {
    q = q.Where(i => i.Components.Contains(c));
}

var result = q.ToArray();
if(result.Length > 1) {
    return result.SingleOrDefault(i => !components.Except(i.Components).Any());
}
else return result.FirstOrDefault();

谁有更好的方法?

【问题讨论】:

    标签: nhibernate hql


    【解决方案1】:

    使用 NHibernate.Linq 提供程序,以下应该可以工作:

    var passed_components = new List<Component>();
    var instance = session.Linq<Instance>()
                          .Where(i => !passed_components.Except(i.Components).Any())
                          .SingleOrDefault();
    

    您可以下载提供程序here 并阅读更多信息herehere

    【讨论】:

    • 你确定这有效吗?我很确定 Contains 只接受一个对象,而不是一个列表。 ActiveRecord 带有一个不允许这样做的 Linq 提供程序。我还检查了 nhcontrib 中的 NHibernate.Linq,它在那里也不起作用。
    • @oillio:我的错误,我很抱歉。但是,我已经编辑了代码的帖子,以比较列表是否包含另一个列表,遵循 bit.ly/aQSE31 。但是,我不是 100% 它会与 NHibernate.Linq 一起使用。
    • 那个版本比我上面的 linq 代码好多了。不幸的是,它也不适用于 NHibernate。
    猜你喜欢
    • 2023-01-18
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2015-10-09
    • 2015-03-27
    • 2020-10-08
    • 1970-01-01
    相关资源
    最近更新 更多