1

マッピング構成ファイルを使用する NHibernate プロジェクトがあります。SQL Server データベースを使用しています。

コードによるマッピングに切り替えたい。私のアプローチは、一度に 1 つのクラスを実行し、切り替えごとにすべてのテストに合格することを確認することです。

2 つのマッピングを混在させるのは非常に簡単です。

  public static ISessionFactory SessionFactory
  {
     get
     {
        if (_sessionFactory == null)
        {
           var configuration = new Configuration();

           configuration.Configure();
           configuration.AddAssembly(typeof(Entities.Player).Assembly);



           var mapper = new NHibernate.Mapping.ByCode.ModelMapper();
           // Here are the entities I've switched to mapping-by-code
           DATMedia.CMS.EntityLibrary.Mappings.ScheduleMediaItem.Map(mapper);
           DATMedia.CMS.EntityLibrary.Mappings.Schedule.Map(mapper);

           configuration.AddMapping(mapper.CompileMappingForAllExplicitlyAddedEntities());
           _sessionFactory = configuration.BuildSessionFactory();
        }
        return _sessionFactory;
     }
  }

しかし、Scheduleマッピングをコードごとのマッピングに変更したとき、重大なパフォーマンスの問題が発生しました。の呼び出しにSession.Flushは 12 秒かかりますが、これはごくわずかな量のテスト データを超えています。

XML マッピングに戻すと、パフォーマンスの問題はなくなりました。

他の誰かが問題を経験しましたか?

schedule明らかな欠陥がある場合に備えて、の前後のマッピングを含めます。

構成ファイル経由:

<?xml version="1.0" encoding="utf-8" ?>
<hibernate-mapping xmlns="urn:nhibernate-mapping-2.2">
   <class name="DATMedia.CMS.EntityLibrary.Entities.Schedule, DATMedia.CMS.EntityLibrary" table="cms_Schedule">
      <id name="Id" column="Id" type="Int64">
         <generator class="identity" />
      </id>
      <property name="Date" column="Date" type="Timestamp" />
      <many-to-one name="SourceTemplate" column="SourceTemplate_Id" class="DATMedia.CMS.EntityLibrary.Entities.ScheduleTemplate, DATMedia.CMS.EntityLibrary" cascade="none" fetch="join" lazy="proxy"/>
     <!-- 
      Note that we are not using cascading deletes here.
      This will be handled by SQL Server through ON DELETE CASCADE foreign key constraints     
     -->
      <bag name="MediaItems" inverse="true" cascade="save-update" lazy="true" order-by="PlayIndex">
         <key column="Schedule_Id" />
         <one-to-many class="DATMedia.CMS.EntityLibrary.Entities.ScheduleMediaItem, DATMedia.CMS.EntityLibrary"/>
      </bag>
     <bag name="PlayerGroups" table="cms_ManyToMany_PlayerGroupSchedules_PlayerGroup_Schedule" lazy="true" cascade="save-update">
       <key column="Schedule_Id" />
       <many-to-many column="PlayerGroup_Id"
                     class="DATMedia.CMS.EntityLibrary.Entities.PlayerGroup, NHibernateManyToMany" />
     </bag>
   </class>
</hibernate-mapping>  

コードによるマッピング:

    public static void Map(ModelMapper mapper)
    {
        mapper.Class<DATMedia.CMS.EntityLibrary.Entities.Schedule>(
            classMapper =>
            {
                classMapper.Table("cms_Schedule");
                classMapper.Id(x => x.Id, map =>
                    {
                        map.Column("Id");
                        map.Generator(Generators.Identity);
                    });
                classMapper.Property(
                        s => s.Date,
                        propertyMapper =>
                        {
                            propertyMapper.Column("Date");
                            propertyMapper.NotNullable(true);
                        }
                );
                classMapper.ManyToOne(
                                s => s.SourceTemplate,
                                manyToOneMapper =>
                                {
                                    manyToOneMapper.Column("SourceTemplate_Id");
                                    manyToOneMapper.Cascade(Cascade.None);
                                    manyToOneMapper.Fetch(FetchKind.Join);
                                    manyToOneMapper.Lazy(LazyRelation.Proxy);
                                }
                );
                classMapper.Bag(
                            s => s.MediaItems,
                            bagPropertyMapper =>
                            {
                                bagPropertyMapper.Key(keyMapper =>
                                                    {
                                                        keyMapper.Column("Schedule_Id");

                                                    }
                                );
                                bagPropertyMapper.Inverse(true);
                                bagPropertyMapper.Cascade(Cascade.Persist);
                                bagPropertyMapper.Lazy(CollectionLazy.Lazy);
                                bagPropertyMapper.OrderBy(smi => smi.PlayIndex);
                            }
                );
                classMapper.Bag(
                        s => s.PlayerGroups,
                        bagPropertyMapper =>
                        {
                            bagPropertyMapper.Key(keyMapper =>
                                {
                                    keyMapper.Column("Schedule_Id");
                                });

                            bagPropertyMapper.Table("cms_ManyToMany_PlayerGroupSchedules_PlayerGroup_Schedule");
                            bagPropertyMapper.Lazy(CollectionLazy.Extra);
                            bagPropertyMapper.Cascade(Cascade.Persist);
                        },
                        collectionElementRelation =>
                            {
                                collectionElementRelation.ManyToMany(manyToManyMapper =>
                                    {
                                        manyToManyMapper.Column("PlayerGroup_Id");
                                    }
                                );
                            }
                    );
            }

            );
    }


後で編集

Flushトランザクション内で呼び出さないことで問題を解決しました。

問題を再現するために、より単純なテスト コードを作成しようとしましたが、うまくいきませんでした (Flush を何度呼び出しても、すべてのテスト コードは非常に高速に実行されます)。これは、一部のエンティティのキ​​ー生成を から に変換したことが原因である可能性がありIdentityますHiLo

私の場合、私のコードは問題を引き起こした特定の構成を作成していたようです。

推測すると、問題を引き起こす構成には、実行時間の長いトランザクションの軽率な使用と ID キーの生成の組み合わせが含まれていると言えます。

4

1 に答える 1

2

私はかなりの数のプロジェクトで混合マッピングを使用しましたが、あなたが説明するように問題は発生していません。フラッシュに12秒かかる理由がわかりません。

混合マッピングの私のテクニックはあなたのテクニックとは少し異なりorderます。あなたが構成することが重要かどうかは100%わかりません。一見の価値があります。http://puredotnetcoder.blogspot.co.uk/2011/07/mixed-mappings-with-hbm-and-mapping-by.htmlを参照してください

すべてのマッピングをエクスポートし、前後で同じであることを再確認したと思いますhttp://puredotnetcoder.blogspot.co.uk/2011/07/view-xml-generated-when-mapping-by-code.htmlを参照してください

于 2012-12-12T09:00:15.680 に答える