Реализация «где не существует» с NHibernate QueryOver - PullRequest
2 голосов
/ 13 апреля 2011

Используя новый QueryOver API в NHibernate, мне нужно сделать что-то эквивалентное:

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.ExpressionProcessor взорвется «неопознанным вызовом метода» на System.Collections.Generic.ICollection<T>.Contains().

Я предполагаю, что должен быть какой-то другой способ сделать это, возможно, с использованием ICriterion, но мои поиски здесь и в Google не дали ничего полезного.

Ответы [ 2 ]

4 голосов
/ 14 апреля 2011

Я просто работаю с той же проблемой, и возможное решение:

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));

Это работает по моим схожим критериям.

3 голосов
/ 13 апреля 2011

Не проверено, но как-то так

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();
}
...