Начало работы со сложной проекцией в nHibernate - PullRequest
3 голосов
/ 24 ноября 2011

Я рассматриваю nHibernate и Entity Framework как возможные ORM для внедрения в систему. Я пытаюсь выполнить эквивалент следующего SQL с помощью nHibernate:

SELECT
   a.Id,
   a.Name,
   a.Etc,
   MAX(CASE WHEN (c.dId IS NOT NULL) THEN 1 ELSE 0 END) As IsLinked
FROM
   tA a
   INNER JOIN tAB ab ON a.Id = ab.aId
   INNER JOIN tB b ON ab.bId = b.Id
   LEFT OUTER JOIN tC c ON b.cId = c.Id
   AND c.dId = 'x'
WHERE
   a.Id = 'y'
GROUP BY
   a.Id,
   a.Name,
   a.Etc,

В основном я хочу выбрать из таблицы tA, а также проверить, связана ли запись в tA с данными в таблице tC. Связь между двумя таблицами сложна:

  • tA имеет отношение многие ко многим к tB (с использованием таблицы tAB)
  • tB имеет отношение один ко многим с таблицей tC с использованием внешнего ключа tB.cId
  • tC имеет внешний ключ tc.dId для другой таблицы tD

Использование кода Entity Framework. Сначала я не могу использовать «Включить», так как он не позволяет фильтровать, но я могу использовать проекцию, чтобы получить функционально правильный запрос, используя:

var query = from a in db.As
            where a.Id == 'y'
            select new
            {
               a,
               IsLinked = a.Bs
                           .Select(b => b.Cs)
                           .Select(c => c.Where(n => n.dId == 'x'))
                           .Select(h => h.Count()).Max() > 0
             };

Сгенерированный SQL сложный и медленный, но работает. Я изо всех сил пытаюсь достичь той же функциональности в nHibernate, начиная с QueryOver:

var query = session.QueryOver<A>().Where(a => a.Id == 'y');

Как создать эквивалентную проекцию, которая работает с несколькими / вложенными типами соединений (один из которых является OUTER объединением), не прибегая к HQL? Или мне лучше (так как производительность, скорее всего, будет плохой) либо:

  • Выполнение двух запросов (один для получения данных и один для установления связи)
  • Представление представлений, которые инкапсулируют сложность объединений

Спасибо

1 Ответ

1 голос
/ 25 ноября 2011

этот запрос должен быть эквивалентен, вы можете попробовать?

var query = from a in db.As
        where a.Id == 'y'
        select new
        {
           a,
           IsLinked = a.Bs.SelectMany(b => b.Cs).Any(c => c.dId == 'x')
           // or
           IsLinked = a.Bs.Any(b => b.Cs.Any(c => c.dId == 'x'))
         };
...