Как сделать эту проекцию в NHibernate? - PullRequest
2 голосов
/ 06 августа 2011

У меня есть эти объекты в моей базе данных

enter image description here

Для данного Job я хочу получить результаты в следующей форме

<Translation>,<ExternalUnit.Text>,<ExternalTranslation.Text>

где условие соединения таково: Translation.Unit.Text == ExternalUnit.Text

Это то, что у меня до сих пор работает нормально:

var props = session.QueryOver<Translation>(() => translation)
            .Select(c => translation.Id, c => externalUnit.Text, c => externalTranslation.Text)
            .JoinAlias(() => translation.TranslationUnit, () => unit)                
            .JoinAlias(() => unit.Job, () => job)
            .Where(() => unit.Job == job)
            .JoinAlias(() => job.ExternalUnits, () => externalUnit)
            .JoinAlias(() => externalUnit.ExternalTranslations, () => externalTranslation)
            .Where(() => externalUnit.Text == unit.Text)
            .List<object[]>();

var translations = session.QueryOver<Translation>(() => translation)                
            .JoinAlias(() => translation.TranslationUnit, () => unit)                
            .JoinAlias(() => unit.Job, () => job)
            .Where(() => unit.Job == job)
            .JoinAlias(() => job.ExternalUnits, () => externalUnit)
            .JoinAlias(() => externalUnit.ExternalTranslations, () => externalTranslation)
            .Where(() => externalUnit.Text == unit.Text)
            .List<Translation>()
            .ToList();

Затем я перебираю translations, ссылаясь на props. Однако мне не нравится этот подход, поскольку я без необходимости выполняю два (почти идентичных) запроса к базе данных вместо одного.

Но я не могу получить желаемую проекцию. Я думал о чем-то вроде этого:

var data = session.QueryOver<Translation>(() => translationAlias)                
            .JoinAlias(() => translation.TranslationUnit, () => unit)                
            .JoinAlias(() => unit.Job, () => job)
            .Where(() => unit.Job == job)
            .JoinAlias(() => job.ExternalUnits, () => externalUnit)
            .JoinAlias(() => externalUnit.ExternalTranslations, () => externalTranslation)
            .Where(() => externalUnit.Text == unit.Text)
            .Select(() => translation, () => externalUnit.Text, () => externalTranslation.Text)
            .List()

но, очевидно, NHibernate не любит бит Select(() => translation...) (он не позволяет мне проецировать всю сущность).

В идеале я бы хотел выбрать анонимные типы, например

var data = session.QueryOver<Translation>()
             ...
             .Select(() => new { A = translation, B = externalTranslation })

но я думаю, что NHibernate там пока нет ...

Большое спасибо за любые предложения.

1 Ответ

0 голосов
/ 07 августа 2011

Я понял! LINQ-провайдер NHibernate спас меня. Что хорошего в этом, так это то, что он может выбирать анонимные типы, что значительно упрощает объединение. На всякий случай, если кому-то интересно, вот для моего конкретного случая:

var q = 
(from c in
  (from b in            
    (from translation in session.Query<Translation>()
     join unit in units on translation.Unit equals unit
     where unit.Job == job
     select new { Translation = translation, Original = unit.Text })         
   join extUnit in externalUnits on job equals extUnit.Job
   where extUnit.Text == b.Original
   select new { Translation = b.Translation, ExternalUnit = extUnit })
 join extTranslation in extTranslations on c.ExternalUnit equals extTranslation.Unit
 select new { Translation = c.Translation, Suggestion = extTranslation })
 .ToList();

SQL, который он генерирует, очень разумный, поэтому я очень рад :))

...