37

私のEF4.3.1モデルには200個の奇数のテーブルがあります。最初の起動はひどいです、数分。DotTraceでキャプチャされたプロファイルは、フレームワークの奥深くにあるいくつかのひどいアルゴリズム/スケーラビリティの選択を意味します。これは、そこにある多数のメソッドへの数百万の呼び出しと3,600万のIEnumerable.Contains()呼び出しによって証明されています。これがスニペットです。これはすべて、データベースで実行された最初のクエリによってトリガーされます(将来のクエリはこれを実行せず、問題ありません)。

ここに画像の説明を入力してください

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

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

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

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/396130

4

3 に答える 3

23

EF6 より前のモデルでは、ビューの生成が遅いことが知られています。今のところ、解決策は事前生成されたビューを使用することです。このようにして、設計時にビューを生成し、実行時にこの作業を回避しています。これを行うには、EF パワー ツールをダウンロードし、[エンティティ データ モデルの最適化] を選択します。ビューを含む C# ファイルがプロジェクトに追加されます。欠点は、モデルが変更されるたびにそれを行う必要があることです。注: ツールを使用してビューを生成するには、実行時にビューを生成するのとほぼ同じ時間がかかります (そのため、忍耐が必要な場合もあります)。役立つ可能性のある EF Power Tools に関する投稿を次に示します

編集

最近、より使いやすい別のソリューションを作成しました (EF6 でのみ動作することに注意してください) - http://blog.3d-logic.com/2013/12/14/using-pre-generated-views-without-事前にビューを生成する必要があります-ef6/

于 2012-05-25T16:06:09.490 に答える
12

これを行う別の方法があります。少し手作業が必要ですが、実際には、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 アプローチ用ではないため、少し変更する必要があることですが、難しいことではありません。

実際に Code First 用の T4 テンプレートを作成しました。私のブログ投稿でダウンロードするリンクを見つけることができます

テンプレートは、Visual Studio Code ギャラリーで利用できるようになりました。すべての詳細が記載された投稿へのリンクは次のとおりです。ギャラリー/

于 2012-05-26T22:47:16.390 に答える
1

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

于 2014-09-15T10:04:32.983 に答える