FluentNHibernate:性能下降时,映射参考与NotFound.Ignore() [英] FluentNHibernate: Performance Penalty when mapping Reference with NotFound.Ignore()

查看:319
本文介绍了FluentNHibernate:性能下降时,映射参考与NotFound.Ignore()的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我用FluentNhibernate,我看到NHibernate的执行许多查询时,协会的引用与 NotFound.Ignore()映射。



由于我的遗留数据库的引用完整性是有点蹩脚,我想知道,如果有一个变通方法,或者如果有一个替代的映射我可以使用。



例如:

  //没有加载实体
参考及LT时查询;使用者名称>(X => X。 ,用户,用户ID)LazyLoad()可空()。

//当我打开我的实体
参考及LT执行了一百查询;使用者名称>(X => x.User,用户ID)。LazyLoad()可空()NOTFOUND 。忽视();


解决方案

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



有一种变通方法,虽然,但它是不漂亮。在实体你需要做沿着这个路线的东西:

 实体类{

私人诠释? _用户名;

私人用户的用户;

公众用户用户
{
获得{
如果(_userId == NULL)
返回NULL;

回报用户;
};
集合{
如果(价值== NULL)
_userId = NULL;
,否则
_userId = value.UserId;

_user =价值;
};
}
}

和在映射你将映射参考正常但没有未找到= ignore设置,但你也映射外键字段:

 引用<使用者>(Reveal.Membmer< ;使用者>(_用户),用户ID)LazyLoad(); 
地图(Reveal.Membmer<&诠释GT;(_用户id))。可空()Not.Update()Not.Insert()。 //禁止更新和插入,使它们不与用户的映射有冲突。



基本上,你让NHibernate的运作正常的在_user字段,然后用_userId现场手工做的空检查。这样就避免了N + 1查询问题。不足之处是它的实体复杂,并会查询更难写。如果你希望能够使用用户属性在LINQ查询,例如,你将不得不暴露出内部_user场并使用它来代替。


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();

解决方案

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.

这篇关于FluentNHibernate:性能下降时,映射参考与NotFound.Ignore()的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆