NHibernate CreateAlias ​​- объединяет произвольные столбцы - PullRequest
4 голосов
/ 27 января 2011

Этот вопрос, кажется, немного поднимается, и я пока не вижу хорошего ответа. У меня есть два класса без внешнего ключа и реальных отношений, кроме общего поля, в данном случае «Заголовок».

Это в значительной степени основано на примере, который я недавно извлек из унаследованного приложения. Мне не разрешено изменять схему, поэтому просто добавить внешний ключ нельзя. Все, что я ищу, - это запрос, который обеспечит все предпосылки для курса с заданным названием:

 select p.* from course c join prereq p on c.title = p.title

Я не ищу отображения, такие как Join (), HasMany () и т. Д., Поскольку все они, очевидно, требуют определенных отношений. Я хочу объединить две таблицы на основе произвольных столбцов без сопоставления.

Подобный вопрос заданный здесь некоторое время назад, кажется, указывает, что возможно использовать CreateAlias ​​(), но я не нашел хороших примеров.

   <class name="Course" table="course">
      <id name="id" column="id" type="long">
        <generator class="identity" />
      </id>
      <property name="Title" column="Title" type="String" />
    </class>

    <class name="Prereq" table="prereq">
      <id name="id" column="id" type="long">
        <generator class="identity" />
      </id>
      <property name="Title" column="Title" type="String" />
      <property name="PrereqTitle" column="PrereqTitle" type="String" />
    </class>

Это то, что я придумал, но, похоже, это не работает. Есть предложения?

        var results = session.CreateCriteria(typeof(Prereq)) 
            .CreateAlias("Course", "C")
            .CreateAlias("Prereq", "P")
            .Add( Expression.EqProperty("C.Title", "P.Title")) 
            .Add( Expression.Eq("C.Title", "Course With Prereq"))
            .List();

Это достаточно просто сделать с LinqToSql, возможно ли это сделать с провайдером Linq для NHibernate? Кажется, что примеры, которые я видел, указывают, что провайдер в основном сводит запрос к любой магии ICriteria / ICriterion, используемой NH - это не представляется возможным, но, пожалуйста, исправьте меня, если я ошибаюсь.

1 Ответ

5 голосов
/ 27 января 2011

Один из способов - создать отдельный критерий и выполнить существование с помощью подзапроса.

var dc = DetachedCriteria.For<Course>("c")
    .SetProjection(Projections.Property("c.Title"))
    .Add(Restrictions.EqProperty("c.Title", "p.Title"));

return Session.CreateCriteria<Prereq>("p")
    .Add(Subqueries.Exists(dc)).List<Prereq>();

Это приведет к созданию следующего предложения sql where: -

WHERE exists (SELECT title as y0_
                   FROM   Course this_0_
                   WHERE  this_0_.Title = this_.Title)
...