Псевдоним соединения nhibernate queryover с предложением where-or

Я просто опубликую код:

public IList<Dish> GetByNameDishTypes(IEnumerable<string> names,
    IEnumerable<string> dishTypes)
{
    // return dishes (ie food) whose name is in the names enumerable,
    // or whose type is in the dish types enumerables
    // (this would be 'breakfast', 'dinner') ..

    var namesArr = names != null ? names.ToArray() : new string[0];
    var dishTypesArr = dishTypes != null ? dishTypes.ToArray() : new string[0];

    var criteria = this.Session.CreateCriteria<Dish>();
    criteria.CreateAlias("DishType", "dt");
    criteria.Add(
        Restrictions.Or
        (
            Restrictions.In("Name", namesArr),
            Restrictions.In("dt.Name", dishTypesArr)
        ));

    return criteria.List<Dish>();

    /* get this to work?
    Dish d = null;
    DishType dt = null;
    return this.Session.QueryOver<Dish>(() => d)
        .JoinAlias(() => d.DishType, () => dt)
        .Where(
            Restrictions.Or
            (
                Restrictions.In(d.Name, namesArr),
                Restrictions.In(dt.Name, dishTypesArr)
            ))
        .List<Dish>(); */
}

Итак, я хотел бы знать, как это сделать с помощью QueryOver. Этот код QueryOver, который я опубликовал, вызывает исключение нулевой ссылки. Код критериев работает.

Спасибо :)


person h.alex    schedule 19.08.2012    source источник


Ответы (1)


Есть несколько способов переписать это в QueryOver, но, вероятно, самый чистый:

Dish d = null;
DishType dt = null;
return this.Session.QueryOver<Dish>(() => d)
    .JoinAlias(() => d.DishType, () => dt)
    .Where(() => d.Name.IsIn(namesArr) || dt.Name.IsIn(dishTypesArr))
    .List<Dish>();

Это сгенерирует SQL, который выглядит примерно так:

SELECT this_.*
FROM   [Dish] this_
       inner join [DishType] dt1_
         on this_.DishTypeId = dt1_.Id
WHERE  (this_.Name in (/* Comma separated list of names */)
         or dt1_.Name in (/* Comma separated list of types */))
person Andrew Whitaker    schedule 19.08.2012
comment
Пытаюсь сделать что-то подобное. Есть ли какой-то конкретный using, который я должен включить, чтобы лямбда-выражения работали правильно? Я получаю сообщения об ошибках () => d и () => dt. - person Sam; 21.08.2013
comment
Невозможно преобразовать лямбда-выражение в тип «строка», поскольку это не тип делегата. У меня есть using System.Linq; и using System.Linq.Expressions; в верхней части файла. Целью приложения является .Net 4. - person Sam; 21.08.2013
comment
@Sam: может быть лучше открыть новый вопрос, чем пытаться понять его в комментариях здесь - person Andrew Whitaker; 21.08.2013
comment
@Андрей, согласен. Просто прокомментировал здесь, потому что у вас, очевидно, это сработало, поэтому потенциально это могло быть что-то простое. - person Sam; 21.08.2013