1

最近のプロジェクトでパフォーマンス テストを行った結果、モデルを再設計し、ネストされたモデルから離れることになりました。誰かが私の理解を正してくれることを期待して、私が見たものを詳しく説明しようと思います.

ネストされた Address を持つ Location モデルから始めました。

public class Location
{
    [Key]
    public int LocationId { get; set; }
    public string Name { get; set; }
    public int? AddressId {get;set;}
    public virtual Address Address{get;set;}
}
public class Address
{
    [Key]
    public int AddressId {get;set;}
    public string Street1 { get; set; }
    public string Street2 { get; set; }
    public string Street3 { get; set; }
    public string City { get; set; }
    public string State { get; set; }
    public string Zip { get; set; }
}

モデルには、コントローラーに LINQ が設定されています (cms は私の DbContext であり、場所とアドレスの DbSets が含まれています)。

public ActionResult ListLocations()
{    
    return View((from l in cms.Locations select l).ToList());
}

ビューは、テーブルに場所を表示するための単純なループでした。

<table id="myTable" class="tablesorter">
    <thead>
        <tr>
            <th>Name</th>
            <th>City</th>
            <th>State</th>
            <th>Zip</th>
        </tr>
    </thead>
    <tbody>
        @if (Model != null)
        {
            foreach (var item in Model)
            {
            <tr>
                <td>@item.Name</td>
                <td>@item.Address.City</td>
                <td>@item.Address.State</td>
                <td>@item.Address.Zip</td>
            </tr>
            }
        }
    </tbody>
</table>

この方法は期待どおりに機能しましたが、完了するまでに平均で約 2000 ミリ秒かかりました。場所を追加するたびに、応答が約 120 ミリ秒遅くなりました。

Stack Exchange の MiniProfiler を使用して、最初にアドレスが表示用に「取得」されるまでの 120 ミリ秒の遅延を特定することができました。後続の場所に同じ住所があった場合、繰り返し表示のパフォーマンス コストは些細なものでした。「名前」プロパティの取得は、すべてのケースで簡単でした。

ネストされたモデルは、親モデルと同時に取得されないようです。

Address のプロパティを直接 Location に結合してモデルをフラット化したとき。平均 300 ミリ秒で完全なリクエストを実行できましたが、場所を追加するときにこのレスポンスにわずかな変更を加えるだけで済みました。

私の質問- Entity Framework は、ネストされたモデルを一度にキャッシュまたは取得する方法を提供しますか、それとも、ネストされたモデルのこの遅延インスタンス化は慣例で必要ですか? ネストされたモデル アプローチとフラット モデルのアプローチで同様の応答時間を達成する方法はありますか?

いつものように、オプションの可能性 c) 明らかな何かが欠けていますか?

4

1 に答える 1

2

メソッドを使用してInclude、クエリに住所を含めてみてください。と同じように:

return View((from l in cms.Locations.Include("Address") select l).ToList());

http://msdn.microsoft.com/en-us/library/bb738708.aspx

コードはクエリを実行して、リスト内の各場所の住所を取得しています。クエリで取得する項目を指定しない場合、EF は遅延読み込みを行い、必要な各オブジェクトは新しいクエリになります。

于 2012-12-05T23:39:26.780 に答える