Vb.net NHibernate多对多标准创建多个数据库调用
我有事件,可以有许多事件类型。我试图使用我定义的NHibernate映射来查询数据库。问题在于,在定义子对象的条件时,NHibernate会重复调用数据库,而不是调用它所需的所有数据。这会导致搜索速度非常慢 数据库表如下所示:Vb.net NHibernate多对多标准创建多个数据库调用,vb.net,nhibernate,fluent-nhibernate,nhibernate-mapping,nhibernate-criteria,Vb.net,Nhibernate,Fluent Nhibernate,Nhibernate Mapping,Nhibernate Criteria,我有事件,可以有许多事件类型。我试图使用我定义的NHibernate映射来查询数据库。问题在于,在定义子对象的条件时,NHibernate会重复调用数据库,而不是调用它所需的所有数据。这会导致搜索速度非常慢 数据库表如下所示: Event -EventID EventType -EventTypeID EventEventTypeID -EventEventTypeID -EventID -EventTypeID 事件类如下所示: Id as Integer Types as IList(
Event
-EventID
EventType
-EventTypeID
EventEventTypeID
-EventEventTypeID
-EventID
-EventTypeID
事件类如下所示:
Id as Integer
Types as IList(Of EventType)
Id as Integer
FullTitle as String
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
EventType类如下所示:
Id as Integer
Types as IList(Of EventType)
Id as Integer
FullTitle as String
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
没有EventType类
NHibernate映射如下所示:
Event
-EventID
EventType
-EventTypeID
EventEventTypeID
-EventEventTypeID
-EventID
-EventTypeID
事件映射
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()
事件类型映射
Table("event.EventType")
Id(Function(x) x.Id).Column("EventTypeID").GeneratedBy().Identity()
Map(Function(x) x.FullTitle).Column("EventTypeFullTitle")
在打开my form时,调用以下函数,该函数为Event的Types属性设置FetchMode
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
但是,当我添加Criteria.Expression时,如下所示(其中QuickSearch是我的用户输入):
我接到1个电话,如下所示:
Id as Integer
Types as IList(Of EventType)
Id as Integer
FullTitle as String
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个,我选择了前50个):
(其中@p0是搜索返回的前50个事件中的每一个)
我觉得这只需要第一个电话
是多对多关系的本质意味着NHibernate需要这些额外的呼叫吗?在我的地图上有什么我遗漏的吗
也许重要的是,我对事件的字符串属性使用了完全相同的技术,从事件到多个关系,搜索只需要一个调用。这个问题似乎只存在于多对多关系中
为这个冗长的问题道歉,并感谢你走了这么远。我已经阅读了许多关于类似主题的问题,但找不到任何解决多对多关系的重复数据库调用问题的方法。您所描述的是一个
nHibernate n+1
问题(基本上执行的查询数与结果集大小成正比),这可能很难解决,具体取决于您的查询有多复杂
虽然不是一个明显的解决方案,但过去对我有效的方法是将联接类型更改为left outer联接,如下所示:
.CreateAlias("Types", "t", NHibernate.SqlCommand.JoinType.LeftOuterJoin)
哇,真管用。现在只有一次对数据库的调用。我很想知道这背后的逻辑。非常感谢你的帮助。