У меня есть события, которые могут иметь много EventTypes. Я пытаюсь запросить базу данных с помощью сопоставлений NHibernate, которые я определил. Проблема в том, что при определении критериев для дочерних объектов NHibernate делает повторные вызовы в базе данных, а не делает один вызов для всех необходимых ему данных. Это приводит к чрезвычайно медленному поиску.NHibernate критерии many-to-many, создающие множественные вызовы базы данных
таблицы базы данных следующим образом:
классEvent
-EventID
EventType
-EventTypeID
EventEventTypeID
-EventEventTypeID
-EventID
-EventTypeID
Событие выглядит следующим образом:
Id as Integer
Types as IList(Of EventType)
Класс EventType выглядит следующим образом:
Id as Integer
FullTitle as String
Там нет EventEventType класс.
NHibernate отображения следующим образом:
EventMapping
Table("event.Event")
Id(Function(x) x.Id).Column("EventID").GeneratedBy().Identity()
HasManyToMany(Of EventType)(Function(x) .Types).Table("event.EventEventType").ParentKeyColumn("EventID").ChildKeyColumn("EventTypeID").Cascade.All()
EventTypeMapping
Table("event.EventType")
Id(Function(x) x.Id).Column("EventTypeID").GeneratedBy().Identity()
Map(Function(x) x.FullTitle).Column("EventTypeFullTitle")
На открытой моей формы, следующая функция вызывается, которая устанавливает FetchMode для Тип свойства Event.
Public Function CreateListViewQuery(currentNHibernateSession As ISession) As NHibernate.ICriteria Implements IListViewQueryable.CreateListViewQuery
Return currentNHibernateSession.CreateCriteria(Of [Event])().SetFetchMode("Types", FetchMode.Join)
End Function
Это используется для заполнения ListView, которое происходит чрезвычайно быстро, только один вызов к базе данных для всех данных:
SELECT TOP (50)
this_.EventID as EventID
, t3_.EventTypeID as EventTyp1_15_0_
, t3_.EventTypeFullTitle as EventTyp2_15_0_
FROM event.Event this_
inner join event.EventEventType types5_ on this_.EventID=types5_.EventID
inner join event.EventType t3_ on types5_.EventTypeID=t3_.EventTypeID
Однако, когда я добавляю Criterion.Expression, как это (где QuickSearch мой пользовательский ввод):
.CreateAlias("Types", "t", NHibernate.SqlCommand.JoinType.InnerJoin)
.Add(NHibernate.Criterion.Expression.Like("t.FullTitle", QuickSearch))
Я получаю 1 вызов, который выглядит следующим образом:
SELECT TOP 50
this_.EventID as EventID12_6_
, types8_.EventID as EventID
, t3_.EventTypeID as EventTyp2_
, t3_.EventTypeFullTitle as EventTyp2_15_0_
FROM
event.Event this_
inner join event.EventEventType types8_ on this_.EventID=types8_.EventID
inner join event.EventType t3_ on types8_.EventTypeID=t3_.EventTypeID
WHERE t3_.EventTypeFullTitle like @p1
И еще 50 вызовов, которые выглядят так (50, как я выбрал TOP 50):
SELECT
types0_.*
FROM
event.EventEventType types0_
left outer join event.EventType eventtype1_ on types0_.EventTypeID=eventtype1_.EventTypeID
WHERE [email protected]
(где @ р0 каждый из 50 главных событий, которые возвращаются при поиске)
Я чувствую, что для этого нужно только первый звонок.
Является ли это отношением «многие ко многим», что означает, что NHibernate нужны эти дополнительные вызовы? Есть что-то в моем картографировании, которое я пропустил?
Возможно, важно, чтобы я использовал ту же технику для свойств String события и отношения «один ко многим» от события, и для поиска требуется только один вызов. Проблема, похоже, существует только со многими отношениями.
Извинения за длинный вопрос, и спасибо за то, что вы достигли этого. Я прочитал много вопросов по подобной теме, но не смог найти решение проблем повторных запросов базы данных для отношений «многие ко многим».
Wow - это работает. Только один звонок в базу данных. Мне хотелось бы узнать, что такое логика. Большое спасибо за вашу помощь. – phillyd