问题:
使用 NHibernate 的 QueryOver 语法检索实体相关集合会导致大量数据库命中。这种行为主要出现在多对多关系中。
原因:
NHibernate 的急切获取机制会针对关系的外键列中找到的每个不同值触发单独的查询。当集合被标记为急切获取但 ISession 不包含所有必需的对象时,会出现此问题。
示例映射:
public class UserRoleMap : ClassMap<UserRole> { public UserRoleMap() { Id(x => x.Id); Map(x => x.RoleName); HasManyToMany(x => x.UsersInRole) .Inverse() .LazyLoad() .Table("UsersInRoles"); } }
场景:
假设您有以下内容data:
使用 Fetch(x => x.UsersInRole) eager 检索 UserRole 时,第一个查询将检索 User1 和 Role1。但是,由于会话不包含与 Role1 关联的所有用户,NHibernate 将执行多个额外查询来获取丢失的用户,从而导致性能下降。
解决方案:
推荐的解决方案是使用 NHibernate 的批量抓取机制,通过设置批量大小collection:
HasManyToMany(x => x.UsersInRole) ... .BatchSize(25)
将批量大小设置为 25 或更高将导致 NHibernate 为延迟加载集合一次检索最多 25 条记录。此优化将在初始查询或最少数量的附加查询中结合获取集合,从而显着减少数据库命中。
以上是如何优化 NHibernate QueryOver 以避免在获取相关集合时多次数据库命中?的详细内容。更多信息请关注PHP中文网其他相关文章!