NHibernate 多对多和 SELECT N+1 问题
我有 4 个数据库表(Channel、User、Message、User2Channel)和相应的实体类:
class **Channel** {
int ChannelId {get;set;}
int ISet<User> UsersToChannel {get;set;}
...
}
class **Message** {
int MessageId {get;set;}
Channel Channel {get;set;}
User User {get;set;}
...
}
class **User**{
int UserId {get;set;}
ISet<Channel> Channels {get;set;}
...
}
我使用 Fluentnhibernate 进行映射:
class **ChannelMap** {
ChannelMap(){
...
HasManyToMany(x => x.UsersInChannel)
.AsSet()
.Cascade.All().Inverse()
.Table("User2Channel")
.Not.LazyLoad();
}
}
class **UserMap** {
UserMap(){
HasManyToMany(x => x.Channels)
.AsSet()
.Cascade.All()
.Table("User2Channel")
.Not.LazyLoad();
}
}
我在此代码中加载消息:
...
var query = session.CreateQuery(@"select m from Message m");
var msgs = query.List<Message>();
...
在探查器中,我看到许多这样的查询:
SELECT ... FROM User2Channel WHERE ChannelId=654
SELECT ... FROM User2Channel WHERE ChannelId=655
etc
请!帮我!我该如何解决这个问题?如果我有数千个频道 - 我也会对数据库进行很多查询!
I have 4 database tables (Channel, User, Message, User2Channel) and according entity classes:
class **Channel** {
int ChannelId {get;set;}
int ISet<User> UsersToChannel {get;set;}
...
}
class **Message** {
int MessageId {get;set;}
Channel Channel {get;set;}
User User {get;set;}
...
}
class **User**{
int UserId {get;set;}
ISet<Channel> Channels {get;set;}
...
}
I use fluentnhibernate for mapping:
class **ChannelMap** {
ChannelMap(){
...
HasManyToMany(x => x.UsersInChannel)
.AsSet()
.Cascade.All().Inverse()
.Table("User2Channel")
.Not.LazyLoad();
}
}
class **UserMap** {
UserMap(){
HasManyToMany(x => x.Channels)
.AsSet()
.Cascade.All()
.Table("User2Channel")
.Not.LazyLoad();
}
}
I load messages in this code:
...
var query = session.CreateQuery(@"select m from Message m");
var msgs = query.List<Message>();
...
At profiler I see many queries like this:
SELECT ... FROM User2Channel WHERE ChannelId=654
SELECT ... FROM User2Channel WHERE ChannelId=655
etc
Please! Help me! How I can solve this problem? If I have many thousands Channels - I get also many queries into database!
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(1)
您可以使用批次加载它们。这是侵入性较小的选项(意味着:您不需要在域代码中执行任何操作)。
我不知道流畅。这就是您需要的 xml 映射:
这可以让 NH 一次预取 50 个通道。它将像这样查询它们:
这使得
N+1
成为N/50+1
。You could load them using batches. This is the less intrusive option (means: you don't need to do anything in your domain code).
I don't know fluent. So this is the xml mapping you need:
This lets NH prefetch 50 channels at once. It will query them like this:
This makes the
N+1
aN/50+1
.