【问题标题】:QueryOver: select ... where property in (...)QueryOver:选择 ... where 属性在 (...)
【发布时间】:2014-09-29 08:25:24
【问题描述】:

我尝试用queryover来表示如下sql:

select * from Table1 t1 where t1.foreign_key in (select t2.Id from Table2 t2 where (...))

所以我为内部选择语句创建了一个子查询,如下所示:

 var sq = QueryOver.Of<Table2>().Where(...).Select(c => c.Id);

但是,当我无法在以下查询中使用此子查询时:

var query = QueryOver.Of<Table1>().WithSubquery.
 WhereProperty(t1 = t1.foreign_key).In(contactSubQuery);

我认为问题在于 QueryOver 期望 Table1 上的子查询而不是 contactSubQuery 中的 Table2,但是我无法访问 Table2 的必需属性。在How do I express a query containing a WHERE..IN subquery using NHibernate's QueryOver API? 中解决了类似的问题(使用JoinAlias),但我看不到如何为我的案例应用该解决方案。感谢您的帮助!

解决方案:

非常感谢@Radim,您几乎是对的。我已经在使用了

Queryover.Of<T>() 

在查询中,但问题是我将其分配给 IQueryOver 变量(因为我们公司没有 var-keyword 样式指南)。在我将它分配给 var 之后,它编译了。由于我根本没想到这会导致问题,因此我将问题中的每个变量都简化为 var ,所以发布的代码实际上应该已经工作了哈哈......我检查了类型并将查询更改为(根据无变量规则):

QueryOver<Table1> = QueryOver.Of<Table1>()
        .WithSubquery
           .WhereProperty(t1 => t1.foreign_key)
           // won't compile, because passed is IQueryOver<T,T>, 
           // not the QueryOver<U>   
           .In(subquery)

我之前在哪里...

IQueryOver<Table1, Table1> = ...

再次感谢您的帮助!

【问题讨论】:

  • 我可以看到,您已经更新了问题,所以我的回答现在可能不准确。但无论如何,如here 所示,我们可以随意嵌套子查询。然后语法仍然相同......它有帮助吗?还是我错过了你真正的问题?
  • 对不起,使用 IsIn 只是因为我尝试了它并从我的解决方案中复制了它。仅使用 .In() 但是,我仍然无法编译:编译器告诉我类似:“方法 TReturn (...).QueryOverSubqueryPropertyBuilderBase<...>.In(QueryOver) 的类型参数不能从用法推断。尝试明确指定参数”。我认为我在子查询中将错误转换为整数/ID 列表,或者在另一个 B 类型的查询中使用 A 类型的子查询时出现问题。
  • 我猜你传递的是session.QueryOver 而不是QueryOver.Of。我用更多解释更新了我的答案。我们很接近,我敢肯定;)

标签: c# .net nhibernate queryover nhibernate-criteria


【解决方案1】:

你快到了,只是语法不是这样的:

var query = QueryOver.Of<Table1>().WithSubquery.
    WhereProperty(t1 = t1.foreign_key).IsIn(contactSubQuery);

但是:

 // subquery "sq"
 var sq = QueryOver.Of<Table2>().Where(...).Select(c => c.Id); 
 var query = QueryOver.Of<Table1>()
            .WithSubquery
               .WhereProperty(t1 => t1.foreign_key)
               .In(sq) // instead of .IsIn(contactSubQuery)
            ...

因为.IsIn()是通用的扩展方法:

/// <summary>
/// Apply an "in" constraint to the named property
///             Note: throws an exception outside of a QueryOver expression
/// 
/// </summary>
public static bool IsIn(this object projection, ICollection values);

.In()是返回结果“QueryOverSubqueryPropertyBuilderBase”的方法.WhereProperty()调用的结果)

另外,请确保传递给 .In(subquery) 的参数是 QueryOver.Of&lt;T&gt;()。例如这是错误

var subquery = session.QueryOver<T>(); // it is named subquery
// but it is not of a type QueryOver<T>, but of a type
// IQueryOver<T, T>
// which is not what is expected here

 var query = QueryOver.Of<Table1>()
            .WithSubquery
               .WhereProperty(t1 => t1.foreign_key)
               // won't compile, because passed is IQueryOver<T,T>, 
               // not the QueryOver<U>   
               .In(subquery)
            ...

这将产生:

错误 1 ​​方法 'NHibernate.Criterion.Lambda.QueryOverSubqueryBuilderBase&lt;NHibernate.IQueryOver&lt;&gt;.... 的类型参数 不能从用法中推断出来。尝试明确指定类型参数。

【讨论】:

    猜你喜欢
    • 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
    相关资源
    最近更新 更多