实施";“不存在的地方”;用NHibernate QueryOver

实施";“不存在的地方”;用NHibernate QueryOver,nhibernate,queryover,Nhibernate,Queryover,使用NHibernate中新的QueryOverAPI,我需要做一些等效的事情: select c.* from Category c where not exists ( select * from CategoryProduct cp where cp.CategoryID = c.Id and cp.ProductID = 'DogFood' ) 换句话说:“给我所有不含狗粮的类别” 我最初的想法是: IEnumerable<Category>

使用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();
}
i无产品的可数FindCategories(产品产品)
{
返回会话
.QueryOver()
其中(c=>c.Products.Contains(产品))
.List();
}
但是,这使得
NHibernate.Impl.ExpressionProcessor
System.Collections.Generic.ICollection.Contains()上出现“无法识别的方法调用”


我想一定有其他方法可以做到这一点,可能涉及到
ICriterion
,但我在这里和谷歌上的搜索没有返回任何有用的信息。

未测试,但类似于此

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();
}
i无产品的可数FindCategories(产品产品)
{
CategoryProduct categoryProductAlias=null;
var subQuery=QueryOver.Of(()=>categoryProductAlias)
.Select(x=>categryProductAlias.ID)
.Where(()=>categoryProductAlias.ProductID==“DogFood”);
类别categoryAlias=null;
返回会话
.QueryOver(()=>类别)
.WithSubquery.WhereProperty(()=>clientAlias.Id).NotIn(子查询)
.List();
}

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

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));
Category别名Category=null;
CategoryProduct别名CategoryProduct=null;
var qcp=查询(()=>aliasCategoryProduct)的版本
.Where(()=>aliasCategoryProduct.ProductID==“DogFood”)
.Where(()=>aliasCategory.Id==aliasCategoryProduct.CategoryID)
.分离标准;
return _session.QueryOver(()=>aliasCategory)
.Where(subquerys.NotExists(qcp));

它适用于我的类似标准。

哪里是“cp.CategoryID=c.Id”限制?在分离的查询中不应该有“Where(()=>categoryProductAlias.CategoryID=categoryAlias.ID)”吗?不能在没有投影的条件上使用子查询。它需要某种类型的投影(即select子句)。实际上,有选择。看看QueryOver,当然。。。Of定义了投影。