2

Fluent NHibernate v2.0.50727 を使用して ASP Web フォーム アプリを SQL サーバー バックエンドに構築しています。

何らかの理由で、小さなデータ (最大 14 行) を含むテーブルのクエリには数秒かかります。

マップはすべて単純です:Id(x => x.Id)Map(x => x.Name). CertificateGroup も Map()ColorRank.

テスト用に nhibernate コードを分離しました:(これは私のアプリケーションを代表するものではありませんが、SO 用に単純化および分離されています)

protected void Page_Load(object sender, EventArgs e)
{
    var config = Fluently.Configure()
                             .Database(MsSqlConfiguration.MsSql2008.ConnectionString("..."))
                             .Mappings(m => m.FluentMappings.AddFromAssemblyOf<PersonMap>())                                 .BuildConfiguration();
    var factory = config.BuildSessionFactory();

    using (var session = factory.OpenSession())
    {
        using (var transaction = session.BeginTransaction())
        {
            var departments = session.QueryOver<DepartmentModel>().List(); // these all take seconds to execute - this has 14 results
            var jobs = session.QueryOver<JobModel>().List(); // 113 results
            var certificates = session.QueryOver<CertificateModel>().List(); //this one about 4 seconds for 210 results
            var groups = session.QueryOver<CertificateGroupModel>().List();

            var association = new CertificateAssociationModel
                {
                    Department = departments.First(),
                    Job = jobs.First(),
                    Certificate = certificates.First(),
                    Group = groups.First()
                };
            session.SaveOrUpdate(association);
            transaction.Commit();
        }
    }
}

nhibernate をエンティティ フレームワークに交換し、上記のコードを実行すると、フェッチは瞬時に行われました。

どんな助けでも感謝します。

編集:

マッピングは次のとおりです (上記で説明したとおり): 部門、ジョブ、証明書の場合:

public class DepartmentMap : ClassMap<DepartmentModel>
{
    public DepartmentMap()
    {
        Table("tblDepartment");
        Id(x => x.Id);
        Map(x => x.Name);
    }
}

CertificateGroupModelも持っています Map(x => x.Rank); Map(x => x.Color);

エンティティ クラスはすべて同じです。

public class CertificateModel
{
    public virtual Int32 Id { get; protected set; }
    public virtual String Name { get; set; }
}

以下も持つCertificateGroupModelを除く:

public virtual String Color { get; set; }
public virtual Int32 Rank { get; set; }

これが私のNHiberateプロファイラーの結果です:

 -- statement #1
begin transaction with isolation level: Unspecified

-- statement #2
SELECT this_.Id   as Id4_0_,
       this_.Name as Name4_0_
FROM   tblDepartment this_

-- statement #3
SELECT this_.Id   as Id5_0_,
       this_.Type as Type5_0_
FROM   tblJobTitles this_

-- statement #4
SELECT this_.Id   as Id2_0_,
       this_.Name as Name2_0_
FROM   tblCertificate this_

-- statement #5
SELECT this_.Id    as Id1_0_,
       this_.Name  as Name1_0_,
       this_.Rank  as Rank1_0_,
       this_.Color as Color1_0_
FROM   tbl_certificate_groups this_

-- statement #6
INSERT INTO lnk_certificate_associations
            (Certificate_id,
             Department_id,
             Job_id,
             Group_id)
VALUES      (1 /* @p0 */,
             1 /* @p1 */,
             1 /* @p2 */,
             1 /* @p3 */);



select SCOPE_IDENTITY()


-- statement #7
commit transaction

nhibprofile http://i.snag.gy/bTKHm.jpg

生成された IL コード:

                      var departments = session.QueryOver<DepartmentModel>().List();
IL_008F: ldloc.2      /* session */
IL_0090: callvirt     instance NHibernate.IQueryOver`2<!!0, !!0> NHibernate.ISession::QueryOver<Core.Domain.Model.DepartmentModel>()
IL_0095: callvirt     instance [mscorlib]System.Collections.Generic.IList`1<!0> NHibernate.IQueryOver`1<Core.Domain.Model.DepartmentModel>::List()
IL_009A: stloc.s      departments
4

2 に答える 2

0

Id の ID ジェネレーターを使用している場合の挿入の質問については、nHibernate は最初にデータベース ( INSERT...SELECT SCOPE_IDENTITY()) にエンティティのレコードを作成するように要求し、次に正しい ID とデータ ( UPDATE)を挿入します。

他のエンティティへの参照は更新されるUPDATEため、「?」のみが表示されることに注意してください。インサートで

于 2013-06-12T13:05:09.433 に答える