Автоматическое объединение с NHibernate / Many-to-one / HQL - PullRequest
0 голосов
/ 21 июля 2010

Я работаю над проектом .NET C #, в котором мне пришлось использовать атрибуты сопоставления NHibernate для сопоставления моих объектов моим таблицам в моей базе данных.

Теперь давайте объясним, в чем моя проблема.

У меня есть два сопоставленных класса, например, ClassA и ClassB. В моей базе данных таблица A содержит внешний ключ, ссылающийся на первичный ключ таблицы B. Следовательно, я добавил в ClassA экземпляр ClassB, отображенный в много-к-одному:

private ClassB b;
[ManyToOne(0, Name = "B", Column = "ID_TABLE_B_TABLE_A", Class = "ClassB", Update = false, Insert = false)]
public virtual ClassB B 
{ 
    get { return b; } 
    set { b= value; } 
}

Теперь я хочу проверить значение поля ClassB при доступе к ClassA. Я пишу запрос на HQL:

Session.CreateQuery("select a.Id from ClassA a where a.ClassB.Name = 'xxx' ");

Вот сгенерированный SQL:

select tablea0_.ID_TABLE_A as col_0_0_ 
from TABLE_A tablea0_, TABLE_B tableb1_
where tablea0_.ID_TABLE_B_TABLE_A = tableb1_.ID_TABLE_B 
and tableb1_.NAME_TABLE_B='xxx'

Я думал, что такого рода HQL-запрос должен был генерировать оператор соединения, а не оператор where, так как я определил связь многих к одному между двумя классами. Примерно так было бы лучше:

select tablea0_.ID_TABLE_A as col_0_0_ 
from TABLE_A tablea0_ 
left join TABLE_B tableb1_ on tableb1_.ID_TABLE_B = tablea0_.ID_TABLE_B_TABLE_A 
where tableb1_.NAME_TABLE_B='xxx'

По-моему, присоединение выглядит чище, где. Я хотел бы знать, есть ли способ соответствующим образом настроить поведение NHibernate, не указывая явно оператор соединения в запросе HQL.

Любая помощь будет оценена!

Ответы [ 3 ]

1 голос
/ 21 июля 2010

Объединение работает так:

Session.CreateQuery("select a.Id from ClassA a join a.ClassB b where b.Name = 'xxx' ");
Session.CreateQuery("select a.Id from ClassA a left join a.ClassB b where b.Name = 'xxx' ");
Session.CreateQuery("select a.Id from ClassA a left outer join a.ClassB b where b.Name = 'xxx' ");

Конечно, теперь вам нужно выяснить, какое объединение подходит вам лучше всего. :)

Дополнительная информация @ http://docs.jboss.org/hibernate/stable/core/reference/en/html/queryhql.html#queryhql-joins

Кстати, если вы хотите быть одним из крутых ребят, вы всегда можете использовать Linq для NHibernate:

var result = Session.Linq<ClassA>().Where(a => a.B.Name == 'xxx').ToList();

Сгенерирует запрос внутреннего соединения.

0 голосов
/ 21 июля 2010

Сгенерированный SQL зависит от диалекта базы данных. Oracle не поддерживал синтаксис объединения ANSI до 9i, поэтому возможно, что диалект Oracle в NHibernate все еще использует старый синтаксис для внутренних объединений. Какой SQL выдается левым соединением? Если это tablea0_.ID_TABLE_B_TABLE_A += tableb1_.ID_TABLE_B, то он также использует старый синтаксис.

0 голосов
/ 21 июля 2010

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

Вы можете попробовать указать «fetch = join» в отображении «многие к одному», но если память служит, это только меняет стратегию, которую NHibernate использует при извлечении связанных сущностей в целом, а не то, как он переводит собственный запрос HQL в SQL .

Но зачем об этом беспокоиться? В 99% случаев я фактически смотрел на сгенерированный SQL, потому что был сгенерирован неправильный SQL (обычно потому, что I допустил ошибку), или для исследования проблем производительности.

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