C# FluentNHibernate:将引用映射到NotFound.Ignore()时的性能损失

C# FluentNHibernate:将引用映射到NotFound.Ignore()时的性能损失,c#,nhibernate,fluent-nhibernate,C#,Nhibernate,Fluent Nhibernate,我使用FluentNhibernate,当关联的引用映射为NotFound.Ignore()时,我看到NHibernate执行许多查询 由于我的遗留数据库的引用完整性有点糟糕,我想知道是否有一个解决方法,或者是否有一个替代映射我可以使用 例如: //no query when loading the entity References<User>(x => x.User, "UserId").LazyLoad().Nullable(); //performs a hundre

我使用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();
//加载实体时没有查询
引用(x=>x.User,“UserId”).LazyLoad().Nullable();
//在加载实体时执行一百个查询
引用(x=>x.User,“UserId”).LazyLoad().Nullable().NotFound.Ignore();

这是一个已知的问题不幸的是,NHibernate JIRA()中存在一个问题

虽然有一个解决办法,但它并不漂亮。在实体中,您需要执行以下操作:

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.
引用(leaver.Membmer(“_user”),“UserId”).LazyLoad();
映射(leave.Membmer(“_userId”)).Nullable().Not.Update().Not.Insert();//抑制更新和插入,以便它们不会与用户的映射冲突。

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

这似乎是NHibernate中的一个bug:不仅仅是任何bug。一个被打开/忽略了4年的bug!这就是为什么这些天我对NHibernate没有信心。人们非常乐意加入新功能,但不会修复不影响它们的bug。更新了bug的链接:。。。可悲的是,6年后它仍然开放。虽然我感谢你的努力,但我真的不想因为这个NHibernate bug而触碰我的顽固无知的实体。我想对我们来说,强制引用完整性更容易,无论如何都必须这样做。不过,谢谢你的帮助。谢谢这一点-我们无法强制RI,因为legacy DB,我将尝试一下,让你知道它是如何工作的!经过一番尝试,这实际上让我们回到了最初的状态,并没有解决我们的问题,我们仍然有一个空assoc和一个N+1问题。您确定N+1问题是由我提到的错误引起的,而不是其他原因吗?因为我的解决方案只是解决这个问题的一个办法。当设置not found=ignore时,NHibernate将在查询后立即为null值发出额外的选择,即使在属性从未被访问的情况下也是如此,并且此解决方案仅通过不使用not found=ignore来避免此问题。我还没有在NHibernate的最新版本中测试过这一点,所以即使没有not found=ignore,它也可能会发出额外的选择(我想我在v2.1中使用过它)。