FluentNHibernate:使用 NotFound.Ignore() 映射引用时的性能损失

发布于 2024-10-18 23:24:30 字数 440 浏览 0 评论 0原文

我使用 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 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

挖鼻大婶 2024-10-25 23:24:30

不幸的是,这是一个已知问题,NHibernate JIRA 中存在一个问题 (https://nhibernate.jira。 com/browse/NH-1001

虽然有一个解决方法,但它并不漂亮。在实体中,您需要按照以下方式做一些事情:

class Entity {

    private int? _userId;

    private User user;

    public User User 
    {
        get { 
            if (_userId == null)
                return null;

            return user;                
        };
        set {
            if (value == null)
                _userId = null;
            else
                _userId = value.UserId;

            _user = value;
        };
    }
 }

在映射中,您将正常映射引用,但没有 not-found =ignore 设置,但您还映射外键字段:

 References<User>(Reveal.Membmer<User>("_user"), "UserId").LazyLoad();
 Map(Reveal.Membmer<int?>("_userId")).Nullable().Not.Update().Not.Insert(); // Suppress updates and inserts so that they don't conflict with the mapping of User.

基本上,您让 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:

class Entity {

    private int? _userId;

    private User user;

    public User User 
    {
        get { 
            if (_userId == null)
                return null;

            return user;                
        };
        set {
            if (value == null)
                _userId = null;
            else
                _userId = value.UserId;

            _user = value;
        };
    }
 }

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:

 References<User>(Reveal.Membmer<User>("_user"), "UserId").LazyLoad();
 Map(Reveal.Membmer<int?>("_userId")).Nullable().Not.Update().Not.Insert(); // Suppress updates and inserts so that they don't conflict with the mapping of User.

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.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文