2

私は次のものを持っていますDomain Model(s)

public class WriteOffApprovalUser
{
    public virtual string UserName { get; set; }
    public virtual Employee Employee { get; set; }
}

public class Employee
{
    public virtual string EmployeeID { get; set; }
    public virtual string EmployeeStatusCode { get; set; }
    public virtual string FirstName { get; set; }
    public virtual string LastName { get; set; }
    public virtual string PreferredName { get; set; }
    public virtual string JobTitle { get; set; }
    public virtual string Division { get; set; }
    public virtual string Department { get; set; }
    public virtual string Location { get; set; }
    public virtual string City { get; set; }
    public virtual string DeskLocation { get; set; }
    public virtual string MailID { get; set; }
    public virtual string Phone { get; set; }
    public virtual string Fax { get; set; }
    public virtual string SecCode { get; set; }
    public virtual string UserId { get; set; }
    public virtual string SupervisorID { get; set; }
}

これらは私のFluent Mappings

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");
    }
}

ここに私のクエリがあります:

var results = new Repository<WriteOffApprovalUser>(session)
                    .Query()
                    .ToList();

これは生成している SQL であり、代わりに JOIN を期待していました。

select writeoffap0_.USER_NAME as USER1_1_ from WRITEOFF_APPROVAL_USER writeoffap0_
SELECT employee0_.EMPLID as EMPLID0_0_, employee0_.USER_ID as USER2_0_0_, employee0_.FIRST_NAME as FIRST3_0_0_, employee0_.LAST_NAME as LAST4_0_0_, employee0_.PREFERRED_NAME as PREFERRED5_0_0_ FROM ADP_EMPLOYEE employee0_ WHERE employee0_.EMPLID=:p0;
SELECT employee0_.EMPLID as EMPLID0_0_, employee0_.USER_ID as USER2_0_0_, employee0_.FIRST_NAME as FIRST3_0_0_, employee0_.LAST_NAME as LAST4_0_0_, employee0_.PREFERRED_NAME as PREFERRED5_0_0_ FROM ADP_EMPLOYEE employee0_ WHERE employee0_.EMPLID=:p0;
SELECT employee0_.EMPLID as EMPLID0_0_, employee0_.USER_ID as USER2_0_0_, employee0_.FIRST_NAME as FIRST3_0_0_, employee0_.LAST_NAME as LAST4_0_0_, employee0_.PREFERRED_NAME as PREFERRED5_0_0_ FROM ADP_EMPLOYEE employee0_ WHERE employee0_.EMPLID=:p0;
SELECT employee0_.EMPLID as EMPLID0_0_, employee0_.USER_ID as USER2_0_0_, employee0_.FIRST_NAME as FIRST3_0_0_, employee0_.LAST_NAME as LAST4_0_0_, employee0_.PREFERRED_NAME as PREFERRED5_0_0_ FROM ADP_EMPLOYEE employee0_ WHERE employee0_.EMPLID=:p0;

現在、データベースには 4 つの行があり、適切なデータが戻ってきていますが、5 つの個別の SQL ステートメントでこれを行うことは期待できません。

4

1 に答える 1

1

SELECT N+1 問題と呼ばれることが多い動作を回避するには、Employee エンティティを熱心にロード/フェッチする必要があります。これを行うには、次の 2 つのオプションがあります。

オプション 1. WriteOffApprovalUser エンティティにクエリを実行すると、常にEmployee テーブルへの JOIN が実行されます。注: これはあなたが望んでいるように聞こえるかもしれませんが、このエンティティで作業するすべての開発者に、この設計上の決定を最後まで固執させることになるため、注意が必要です。WriteOffApprovalUser テーブルに対してクエリを実行し、Employee テーブルへの JOIN を実行したくないだろうか、自問する必要があります。答えが「はい」の場合は、マッピング ファイルで熱心な読み込みを強制しないでください。

Employee を自動的に取得するには、マッピングの HasOne コードを次のように変更します。

HasOne(x => x.Employee).PropertyRef("UserId").Not.LazyLoad().Fetch.Join();

オプション 2.クエリで熱心な読み込みを実行します。何らかの種類の T パターンのリポジトリを使用していることに気付きました。熱心な読み込みを処理するには、それを変更する必要があるかもしれません。NHibernate.Linq 名前空間でNHibernate の組み込み LINQQuery<T>クラスを使用した典型的な熱心な読み込みは、次のようになります。

var results = new session.Query<WriteOffApprovalUser>()
                    .Fetch( x => x.Employee ) // This will tell NHibernate to perform a JOIN to the Employee table
                    .ToList();
于 2013-03-29T00:55:00.283 に答える