web-dev-qa-db-ja.com

Entity Frameworkの初期化が遅い-bootstrapそれを高速化するにはどうすればよいですか?

私のEF 4.3.1モデルには200奇数のテーブルがあります。最初の起動は恐ろしい、数分です。 DotTraceでキャプチャされたプロファイルは、フレームワークの奥深くにあるいくつかの恐ろしいアルゴリズム/スケーラビリティの選択を暗示しています。これがスニペットです。これはすべて、データベースで実行された最初のクエリによってトリガーされます(将来のクエリはこれを行わず、問題ありません)。

enter image description here

これを痛みを軽減するために、モデルに何ができますか?これをどうにかしてプリコンパイルできますか?できれば、EFチームがこれらの問題に対処したり、フレームワークをオープンソースにしたりして、私ができるようにすることはできますか?または、少なくともWarapperのスペルを修正しますか? :)

編集:これをトリガーする特定のEF呼び出しは基本的にvar db = new MyDbContext(); db.Personnel.Where(a => a.Login == login).SingleOrDefault();です。また、EF Migrations Seed()AddOrUpdateは、実質的に同じスタックを生成します。もう少しコンテキストを与える可能性のあるより完全なスタックトレースは、次のとおりです。 Fuller Stack Trace

編集:いくつかの関連リンク:

EDIT2:彼らはちょうど オープンソース コードなので、次の行が表示されます:

//Filter the 1:1 foreign key associations to the ones relating the sets used in these cell wrappers.
oneToOneForeignKeyAssociationsForThisWrapper =
    oneToOneForeignKeyAssociationsForThisWrapper.Where(
        it => (it.AssociationEndMembers.All(endMember => entityTypes.Contains(endMember.GetEntityType()))));

いくつかの作業が必要なものです。おそらく必要ないときにO(n ^ 2)アルゴリズムを使用していますが、まだ詳しく調べていません。

EDIT3:幸い、EF6での作業がこのコードを修正しているようです: http://entityframework.codeplex.com/discussions/3961

36
Scott Stafford

EF6より前のバージョンでは、大きなモデルではビューの生成が遅いことがわかっています。当面の解決策は、事前に生成されたビューを使用することです。このようにして、設計時にビューを生成し、実行時にこの作業を回避します。これを行うには、EFパワーツールをダウンロードし、[エンティティデータモデルの最適化]を選択します。ビューを含むプロジェクトにC#ファイルを追加します。欠点は、モデルが変更されるたびにそれを行う必要があることです。注:ツールでビューを生成するには、実行時にビューを生成するのとほぼ同じ時間がかかります(そのため、辛抱する必要がある場合があります)。参考になるかもしれないEF Power Toolsに関する投稿を以下に示します。 http://blogs.msdn.com/b/adonet/archive/2011/05/18/ef-power-tools-ctp1-released.aspx

編集

最近、私ははるかに使いやすい別のソリューションを作成しました(EF6でのみ機能することに注意してください) http://blog.3d-logic.com/2013/12/14/using-pre-generated- views-without-having-to-pre-generate-views-ef6 /

23
Pawel

これを行う別の方法を次に示します。少し手作業が必要ですが、実際にはMsBuildを使用するシナリオに適しています。 Power Toolsを使用してビューを作成する代わりに(機能しなかったとのこと、残念ですが)ビューを手動で作成することができます。手順は次のとおりです。

  • 最初に、コンテキストのアーティファクトを取得する必要があります。 csdl、ssdl、mslファイルのすべてが必要です。 EdmxWriterを使用してこれらを取得できます。 EdmxWriterは、3つのファイルすべてを結合したedmxファイルを返すため、それらを分割する必要があることに注意してください。このステップのコードは次のとおりです(名前空間はEF4に固有です。EF5および.NET Framework 4.5の使用を検討している場合は、それに応じて変更するか、完全修飾名ではなくローカル名のみで要素を選択する必要があります)。

    var ms = new MemoryStream();
    using (var writer = XmlWriter.Create(ms))
    {
        EdmxWriter.WriteEdmx(new Context(), writer);
    }

    ms.Position = 0;

    var xDoc = XDocument.Load(ms);

    var ssdl = xDoc.Descendants("{http://schemas.Microsoft.com/ado/2009/02/edm/ssdl}Schema").Single();
    var csdl = xDoc.Descendants("{http://schemas.Microsoft.com/ado/2008/09/edm}Schema").Single();
    var msl = xDoc.Descendants("{http://schemas.Microsoft.com/ado/2008/09/mapping/cs}Mapping").Single();

    ssdl.Save("Context.ssdl");
    csdl.Save("Context.csdl");
    msl.Save("Context.msl");
  • アーティファクトがある場合、EdmGenツールを使用してビューを生成できます。ここでは手動で行うため、VSコマンドプロンプトから行う必要があります。次に、ビューを生成するために使用するコマンドを示します。
EdmGen /mode:ViewGeneration /incsdl:Context.csdl  /inmsl:Context.msl /inssdl:Context.ssdl /outviews:Context.Views.cs
  • 生成されたファイルをプロジェクトに追加します。

ビュー生成をビルドシステムと統合する場合は、もう1つの興味深いオプションがあります。T4テンプレートを使用することです。テンプレートは上記のステップを処理します。このアプローチの詳細については、こちらをご覧ください http://blogs.msdn.com/b/adonet/archive/2008/06/20/how-to-use-a-t4-template-for-view -generation.aspx 。唯一の問題は、この例はCodeFirstアプローチ用ではないため、少し変更する必要があるので、難しくないはずです。

実際にコードファースト用のT4テンプレートを作成しました。ダウンロードへのリンクは私のブログの投稿にあります: http://blog.3d-logic.com/2012/05/28/entity-framework-code-first-and-pre-generated-views/

テンプレートがVisual Studioコードギャラリーで利用できるようになりました。詳細がすべて記載された投稿へのリンクは次のとおりです。 http://blog.3d-logic.com/2012/06/13/entity-framework-codefirst-view-generation-templates-on-visual- studio-code-gallery /

12
Pawel

現在のバージョンのEntity Frameworkでは、ビューの生成は実際には非常に高速です。 (6.1)準備中の別のより幅広いキャッシングソリューションがあります: https://entityframework.codeplex.com/workitem/1876 。このパッチが受け入れられるのを待つか、十分に勇気がある場合は、自分で適用できます。

1