Nhibernate 映射可能没有行的扩展表

Nhibernate 映射可能没有行的扩展表,nhibernate,fluent-nhibernate,nhibernate-mapping,Nhibernate,Fluent Nhibernate,Nhibernate Mapping,我正在使用Fluent nHibernate处理一个遗留数据库,有一个主Person表和几个扩展表,其中包含有关此人的附加信息。这些扩展表是一对一的,这意味着一个人在扩展表上只有一行,扩展表应该始终映射回一个人 表格:个人 列:人名、名、姓等 表格:个人登录 列:PersonID(FK,唯一)、用户名、密码等 我的映射定义如下(省略了不相关的属性): 当我在两个表上都有数据时,这是可行的,但我最近了解到一些扩展表并没有所有Person行的数据。这导致我在查询过程中出错。因此,我在PersonMa

我正在使用Fluent nHibernate处理一个遗留数据库,有一个主Person表和几个扩展表,其中包含有关此人的附加信息。这些扩展表是一对一的,这意味着一个人在扩展表上只有一行,扩展表应该始终映射回一个人

表格:个人
列:人名、名、姓等

表格:个人登录
列:PersonID(FK,唯一)、用户名、密码等

我的映射定义如下(省略了不相关的属性):

当我在两个表上都有数据时,这是可行的,但我最近了解到一些扩展表并没有所有Person行的数据。这导致我在查询过程中出错。因此,我在PersonMap中添加了
.NotFound.Ignore()
,使其看起来像这样:

   References(x => x.Login, "PersonID").LazyLoad().NotFound.Ignore();
这导致我从登录表中获得不必要的选择,因为我的业务层不需要投影任何扩展表值。这导致我的一些搜索查询的性能非常糟糕

我浏览了很多帖子,但还没有找到一个关于如何应对这种情况的可靠答案。以下是我尝试过的选项:


选项一:

在扩展表上创建行以确保没有人在扩展表上没有行,然后删除
.NotFound.Ignore()

这个选项的问题是它是一个遗留数据库,我不确定需要在哪里进行更新以确保在插入人员时插入PersonLogin


选项二:

从我的PersonMap中删除PersonLogin引用,并在我的Person类中自定义加载它。像这样:

public class Person
{
    /// <summary> Gets or sets the PersonID </summary>
    public virtual int Id { get; set; }

    private bool loadedLogin;
    private PersonLogin login;
    public virtual PersonLogin Login
    {
        get
        {
            if (!loadedLogin)
            {
                login = SessionManager.Session().Get<PersonLogin>(Id);
                loadedLogin = true;
            }

            return login;
        }
        set
        {
             login = value;
             loadedLogin = true;
        }
    }
}
我把它添加到配置中

cfg.EntityNotFoundDelegate = new CustomEntityNotFoundDelegate();
它捕获我的场景并返回,而不是抛出错误,但是现在当我尝试将那些PersonLogin属性投影到我的业务对象上时,它尝试使用代理对象并抛出这个错误,我试图弄清楚我是否可以干净地处理这个错误(可能在IPostLoadEventListener中)


我想通过保持
.NotFound.Ignore()
,我现在已经实现了这一点

我最初说:

这导致我从登录表中获得不必要的选择,因为我的业务层不需要投影任何扩展表值。这导致我的一些搜索查询的性能非常糟糕

我能够调整我的LINQ查询,以便在某些情况下使用IQueryOver,并改进我在其他情况下对LINQ的使用,以便只投影必要的值。这似乎已经解决了从拉回扩展表的查询,因为在投影中不需要它们的值


我认为我的查询并没有投影这些扩展表,但我发现我有一个方法ToKeyValuePair,我在投影中使用它将ID和Name字段连接到一些相关属性中。该方法导致对象完全加载,因为LINQ无法在不加入扩展表的情况下确定所需字段是否存在。

看起来您现在找到了解决方案。我们试着将所有问题都保持在问答形式:1个问题,0个或多个答案。我已经把你的一些“答案”转换成了问题,而不是答案,但最后一个看起来至少是答案的一部分。如果你能编辑这篇文章,让它的问答风格比我做的稍微好一点,那就太好了。谢谢@Flexo。我最初把这些都写在了一起,但我决定把这些选项作为单独的答案发布,因为我认为它提供了一个更好的讨论,并允许人们否决不好的选项。无论如何,我清理了帖子和答案并接受了。非常感谢。
private class CustomEntityNotFoundDelegate : IEntityNotFoundDelegate
{
    public void HandleEntityNotFound(string entityName, object id)
    {
        if (entityName == "my.namespace.PersonLogin")
        {
            return;
        }
        else
        {
            throw new ObjectNotFoundException(id, entityName);
        }
    }
}
cfg.EntityNotFoundDelegate = new CustomEntityNotFoundDelegate();
System.Reflection.TargetException occurred
Message = Non-static method requires a target