使用NHibernate QueryOver实现“where not exists”

时间:2011-04-13 09:17:40

标签: nhibernate queryover

在NHibernate中使用新的QueryOver API,我需要做类似的事情:

select c.*
from Category c
where not exists (
    select *
    from CategoryProduct cp
    where cp.CategoryID = c.Id
    and cp.ProductID = 'DogFood'
)

换句话说:“给我所有不含狗粮的类别。”

我最初的想法是这样的:

IEnumerable<Category> FindCategoriesWithoutProduct(Product product)
{
    return _session
        .QueryOver<Category>()
        .Where(c => c.Products.Contains(product))
        .List();
}

但是,这会导致NHibernate.Impl.ExpressionProcessorSystem.Collections.Generic.ICollection<T>.Contains()上出现“无法识别的方法调用”。

我认为必须有其他方法可以执行此操作,可能涉及ICriterion,但我在此处和Google上的搜索没有返回任何有用的内容。

2 个答案:

答案 0 :(得分:4)

我只是遇到了同样的问题,可能的解决方案是:

Category aliasCategory = null;
CategoryProduct aliasCategoryProduct = null;

var qcp = QueryOver.Of<CategoryProduct>(() => aliasCategoryProduct)
          .Where(() => aliasCategoryProduct.ProductID == "DogFood")
          .Where(() => aliasCategory.Id == aliasCategoryProduct.CategoryID)
          .DetachedCriteria;

return _session.QueryOver<Category>(() => aliasCategory)
               .Where(Subqueries.NotExists(qcp));

它符合我的类似标准。

答案 1 :(得分:3)

未经测试,但有类似的内容

IEnumerable<Category> FindCategoriesWithoutProduct(Product product)
{
    CategoryProduct categoryProductAlias = null;
    var subQuery = QueryOver.Of<CategoryProduct>(() => categoryProductAlias)   
        .Select(x => categryProductAlias.ID)
        .Where(() => categoryProductAlias.ProductID == "DogFood");

    Category categoryAlias = null;
    return _session
        .QueryOver<Category>(() => categoryAlias)
        .WithSubquery.WhereProperty(() => clientAlias.Id).NotIn(subQuery)
        .List();
}