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