我想使用nHhibernate通过内存集合过滤db表(使用复合键Id1和Id2)。
class Item{ int Id1; int Id2; }
var collection = new List<Item>();
var list = _session
.QueryOver<MyDbTable>()
.Where(x => collection.Any(y => y.Id1 == x.Id1 && y.Id2 == x.Id2))
.List();
我这样做的错误是“无法识别的方法调用:System.Linq.Enumerable:Boolean Any”。我还尝试使用FirstOrDefault方法并将结果与null进行比较,但它不起作用。
答案 0 :(得分:3)
你不能在NHibernate中使用Linq方法。
如果要验证属性是否在集合中,可以使用IsIn
方法,但在您的情况下,我们不想检查单个属性是否在集合中,我们正在寻找复合键。
要解决您的问题,您可以迭代collection
来构建限制:
var disjunctionOptions = new Disjunction();
foreach (var item in collection)
{
var conjunction = new Conjunction();
conjunction.Add<MyDbTable>(x => x.Id1 == item.Id1);
conjunction.Add<MyDbTable>(x => x.Id2 == item.Id2);
disjunctionOptions.Add(conjunction);
}
var list = _session
.QueryOver<MyDbTable>()
.Where(disjuntionOptions)
.List();
通过它,您将使用复合键获得正确的查询结果。
注意:
IsIn
用于检查单个属性是否在收集(或数组)中。如果单独使用(在每个属性中),它将给出错误的结果,因为您正在使用复合键。
答案 1 :(得分:1)
在相信您使用QueryOver API时,可能会让您感到困惑并使用linq-to-nhibernate。在这种情况下,要使用linq2nh,请将代码更改为:
using NHibernate.Linq;
...
var collection = new List<Item>();
var list = _session
.Query<MyDbTable>()
.Where(x => collection.Any(y => y.Id1 == x.Id1 && y.Id2 == x.Id2))
.ToList();
将using
切换为QueryOver
需要Query
,因为ISession.Query
是NHibernate.Linq
命名空间中定义的扩展方法。使用Linq API而不是QueryOver
时,必须将List
方法调用更改为ToList
。