NHibernate QueryOver按集合过滤

时间:2016-03-29 16:26:05

标签: c# linq nhibernate

我想使用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进行比较,但它不起作用。

2 个答案:

答案 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时,可能会让您感到困惑并使用。在这种情况下,要使用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.QueryNHibernate.Linq命名空间中定义的扩展方法。使用Linq API而不是QueryOver时,必须将List方法调用更改为ToList