FluentNHibernate:使用 NotFound.Ignore() 映射引用时的性能损失
我使用 FluentNhibernate,并且当使用 NotFound.Ignore()
映射关联引用时,我看到 NHibernate 执行许多查询。
由于我的遗留数据库的引用完整性有点糟糕,我想知道是否有解决方法或者是否有我可以使用的替代映射。
例子:
//no query when loading the entity
References<User>(x => x.User, "UserId").LazyLoad().Nullable();
//performs a hundred queries when I load my entities
References<User>(x => x.User, "UserId").LazyLoad().Nullable().NotFound.Ignore();
I use FluentNhibernate and I see NHibernate performing many queries when references of associations are mapped with NotFound.Ignore()
.
Since the referential integrity of my legacy database is kinda crappy, I'd like to know if there's a workaround or if there's an alternative mapping I can use.
Example:
//no query when loading the entity
References<User>(x => x.User, "UserId").LazyLoad().Nullable();
//performs a hundred queries when I load my entities
References<User>(x => x.User, "UserId").LazyLoad().Nullable().NotFound.Ignore();
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(1)
不幸的是,这是一个已知问题,NHibernate JIRA 中存在一个问题 (https://nhibernate.jira。 com/browse/NH-1001)
虽然有一个解决方法,但它并不漂亮。在实体中,您需要按照以下方式做一些事情:
在映射中,您将正常映射引用,但没有 not-found =ignore 设置,但您还映射外键字段:
基本上,您让 NHibernate 正常运行在 _user 字段上,然后使用 _userId 字段手动执行 null 检查。这样就可以避免 N+1 选择问题。缺点是它使实体变得复杂并且使查询更难编写。例如,如果您希望能够在 LINQ 查询中使用用户属性,则必须公开内部 _user 字段并使用它。
This is a known problem unfortunately, there is an issue in NHibernate JIRA (https://nhibernate.jira.com/browse/NH-1001)
There is a workaround though but it isn't pretty. In the Entity you need to do something along the lines of this:
And in the mapping you would map the reference as normal but without the not-found = ignore setting but you also map the foreign key field:
Basically you let NHibernate operate as normal on the _user field and then use the _userId field to manually do the null check. This way you avoid the N+1 selects problem. The downside is that it complicates the Entity and will make queries harder to write. If you want to be able to use the User-property in a LINQ query for example you will have to expose the internal _user field and use that instead.