4

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

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

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

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

Аналогичный вопрос asked here a a назад, кажется, указывает, что это возможно с помощью 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 - это не представляется возможным, но, пожалуйста, исправьте меня, если я ошибаюсь.

ответ

5

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

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 exists (SELECT title as y0_ 
        FROM Course this_0_ 
        WHERE this_0_.Title = this_.Title)