NHibernate一对一关系

NHibernate一对一关系,nhibernate,fluent-nhibernate,Nhibernate,Fluent Nhibernate,我有以下域模型: 这些是我的Fluent映射 public class WriteOffApprovalUserMap : ClassMap<WriteOffApprovalUser> { public WriteOffApprovalUserMap() { //Schema("LEGAL"); Table("WRITEOFF_APPROVAL_USER"); Id(x => x.UserName).Column

我有以下
域模型

这些是我的
Fluent映射

public class WriteOffApprovalUserMap : ClassMap<WriteOffApprovalUser>
{
    public WriteOffApprovalUserMap()
    {
        //Schema("LEGAL");
        Table("WRITEOFF_APPROVAL_USER");

        Id(x => x.UserName).Column("USER_NAME");

        HasOne(x => x.Employee).PropertyRef("UserId");

    }
}

public class EmployeeMap : ClassMap<Employee>
{
    public EmployeeMap()
    {
        // Table Name
        //Schema("ADP_FEED_OWNER");
        Table("ADP_EMPLOYEE");

        // Primary Key
        Id(x => x.EmployeeID).Column("EMPLID");

        // Mappings
        Map(x => x.UserId).Column("USER_ID");
        Map(x => x.FirstName).Column("FIRST_NAME");
        Map(x => x.LastName).Column("LAST_NAME");
        Map(x => x.PreferredName).Column("PREFERRED_NAME");
    }
}

现在数据库中有四行,正确的数据正在返回,但我不希望有五个单独的SQL语句来执行此操作。

您需要立即加载/获取Employee实体,以避免您看到的行为,这通常被称为SELECT N+1问题。为此,您有两个选择:

选项1。映射意义中的渴望加载当您查询WriteOffApprovalUser实体时,它将始终执行到Employee表的联接。注意:这听起来像是你想要的,但是要小心,因为你会迫使所有曾经使用这个实体的开发人员一直坚持这个设计决策,直到时间结束。您必须扪心自问,我是否希望查询WriteOffApprovalUser表并执行到Employee表的联接。如果答案是肯定的,那么不要强制在映射文件中加载

要让员工自动获取,请在映射中更改HasOne代码,使其如下所示:

HasOne(x => x.Employee).PropertyRef("UserId").Not.LazyLoad().Fetch.Join();
var results = new session.Query<WriteOffApprovalUser>()
                    .Fetch( x => x.Employee ) // This will tell NHibernate to perform a JOIN to the Employee table
                    .ToList();
选项2。在查询中执行即时加载。我注意到您正在使用某种类型的T模式存储库,因此您可能需要修改它以处理紧急加载。在NHibernate中使用NHibernate的内置LINQ
Query
类进行典型的即时加载。LINQ命名空间如下所示:

HasOne(x => x.Employee).PropertyRef("UserId").Not.LazyLoad().Fetch.Join();
var results = new session.Query<WriteOffApprovalUser>()
                    .Fetch( x => x.Employee ) // This will tell NHibernate to perform a JOIN to the Employee table
                    .ToList();
var results=newsession.Query()
.Fetch(x=>x.Employee)//这将告诉NHibernate执行到Employee表的联接
.ToList();

非常可靠的答案!!非常感谢。一个问题是,为什么存在选择N+1问题?我撒谎了,另一个问题。如果我将映射更改为this
HasOne(x=>x.Employee).ForeignKey(“USER_ID”).constrated()
然后我只会得到
writeofApprovalUser
,直到我在查询中调用
Fetch(x=>x.Employee)
,但是对于
PropertyRef
我仍然会遇到选择N+1的问题。@SamStriano我会把选择N+1的解释推迟到谷歌和这个堆栈溢出问题:@SamStriano老实说,我不能告诉你为什么。我的猜测是它与约束属性有关,但我真的不知道。我从来没有完全理解过约束属性,即使只是在这里阅读了关于它的官方NHibernate文档:
var results = new session.Query<WriteOffApprovalUser>()
                    .Fetch( x => x.Employee ) // This will tell NHibernate to perform a JOIN to the Employee table
                    .ToList();