Как использовать linq-to-nhibernate для запроса унаследованных классов? - PullRequest
2 голосов
/ 03 ноября 2010

Предположим, у меня есть классы Animal, Cat и Dog. Cat и Dog наследуются от Animal. Рассмотрим следующий код:

var query = from animal in session.Linq<Animal>()
            where 
            animal.Color == "White"
            select animal;

Как добавить критерий к вышеуказанному запросу для запроса типа объекта? Например что-то вроде animal.Type == typeof(Cat).

Ответы [ 3 ]

11 голосов
/ 04 ноября 2010

Это поддерживается в новом провайдере:

var query = from animal in session.Query<Animal>()
            where animal.Color == "White" &&
                  animal is Cat
            select animal;
1 голос
/ 16 ноября 2010

Вы можете отобразить свойство только для чтения, которое использует ваш столбец дискриминатора как часть формулы. Запросы к этому столбцу позволят вам различать типы с текущим поставщиком nhcontrib.

Дальнейшие указания можно найти в моем ответе на похожий вопрос здесь .

1 голос
/ 04 ноября 2010

Версия LINQ-to-NHibernate, совместимая с NH 2.1.2, не поддерживает запросы по типу во время выполнения.

// DOES NOT WORK WITH NH 2.1.2 & LINQ-to-NH
var desiredType = typeof(Cat);
var query = from animal in session.Linq<Animal>()
            where animal.Color == "White"
               && animal.GetType() == desiredType
            select animal;
// This results in an ArgumentOutOfRangeException in the LINQ provider

Вы можете сделать это в памяти, как предложено в комментариях:

var desiredType = typeof(Cat);
var query = from animal in session.Linq<Animal>()
            where animal.Color == "White"
            select animal;
var animals = query.ToList();
var whiteCats = from animal in animals.AsQueryable()
                where animal.GetType() == desiredType
                select animal;

Выполняя query.ToList (), вы считываете всех белых животных и затем выполняете запрос типа, используя LINQ-to-Objects.(В зависимости от вашего точного запроса и сопоставления вам, возможно, придется беспокоиться о ленивых прокси-серверах и, следовательно, проверять, можно ли назначить тип объекта для нужного типа.) Это имеет главный недостаток, заключающийся в считывании большего количества данных, чем необходимо для фильтрации по животным.введите в память.В зависимости от вашего домена и запроса, это может быть или не быть большой проблемой.

Если вы не можете выполнить обновление до магистрали NHibernate (иначе NH3), я бы порекомендовал не использовать LINQ-to-NHibernate для этого запроса ивместо этого, используя Критерии.

var desiredType = typeof(Cat);
var query = session.CreateCriteria(desiredType)
                   .Add(Restrictions.Eq("Color", "White")
                   .List<Animal>();

NB Это должно быть очевидно, но позвольте мне просто заявить об этом явно.Нет никаких причин, по которым вы не можете использовать критерии для этого запроса и LINQ-to-NHibernate для других ваших запросов.Вы можете свободно комбинировать методы запросов в NHibernate.

...