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

Fal*_*con 3 c# nhibernate fluent-nhibernate

我使用FluentNhibernate,我看到NHibernate在映射关联的引用时执行了很多查询NotFound.Ignore().

由于遗留数据库的参照完整性有点糟糕,我想知道是否有解决方法,或者是否有可以使用的替代映射.

例:

//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();
Run Code Online (Sandbox Code Playgroud)

Sam*_*ter 6

遗憾的是,这是一个已知问题,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;
        };
    }
 }
Run Code Online (Sandbox Code Playgroud)

在映射中,您可以将引用映射为正常但没有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.
Run Code Online (Sandbox Code Playgroud)

基本上你让NHibernate在_user字段上正常运行,然后使用_userId字段手动进行空检查.这样就可以避免N + 1选择问题.缺点是它使实体复杂化并使查询更难写.例如,如果您希望能够在LINQ查询中使用User-property,则必须公开内部_user字段并使用它.