QueryOver:select ... where(...)中的属性

时间:2014-09-29 08:25:24

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

我尝试使用queryover来表示以下sql:

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

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

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

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

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

我认为问题在于QueryOver期望在ContactSubQuery中使用Table1而不是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中的问题,所以发布的代码实际上应该已经工作了大声笑...我检查了类型并简单地将查询更改为(根据no-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> = ...

再次,非常感谢您的帮助!

1 个答案:

答案 0 :(得分:2)

你几乎就在那里,只是语法不是这样的:

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<T>()。例如,错误

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<NHibernate.IQueryOver<>的类型参数....   无法从使用中推断出来。尝试显式指定类型参数。