別の LINQ 結合ステートメントで既に読み込まれている関連プロパティに対して、モデルが再び DB に移動するのはなぜですか?
背景情報:
最近、ASP.NET MVC3 Linq アプリケーションでいくつかのパフォーマンス プロファイリングを実行しましたが、解決したい不可解な結果が得られました。
これは、db 構造の簡略化されたバージョンです。外部キー関係が設定されます。
テーブル クライアント:
ID|Client Name|Vertical ID|
___________________________
1 |Client1 |2 |
2 |Client2 |5 |
3 |Client3 | |
テーブル垂直
ID|Vertical Name|
_________________
2 |Life |
5 |Guilt |
クライアントのリストを表示すると、クライアント名と垂直方向が表示されます。私のコントローラーはシンプルです:
public ActionResult Index()
{
...
var model = repository.GetAllClients();
return View(model);
}
すべてのクライアントを取得すると、垂直テーブル (および他のいくつか) で結合が実行されます。
public IEnumerable<client> GetAllClients()
{
OperationsMetricsDataContext db = new OperationsMetricsDataContext();
var clients = from c in db.clients
join v in db.verticals on c.vertical equals v into tmp1
from v in tmp1.DefaultIfEmpty()
join sm in db.cel_sm_staffs on c.sm_id equals sm.cel_sm_id into tmp2
from sm in tmp2.DefaultIfEmpty()
join cel in db.cel_sm_staffs on c.cel_id equals cel.cel_sm_id into tmp3
from cel in tmp3.DefaultIfEmpty()
select c;
return clients;
}
私のビューでは、部分的なクライアント クラスでこのメソッドを使用してバインドした垂直方向の名前を表示しようとします。
public string getVerticalName()
{
return this.vertical == null ? "N/A" : this.vertical.vertical_name;
}
問題:
@foreach (var item in Model) {
<tr>
<td>
@Html.Raw(item.client_name)
</td>
<td>
@Html.Raw(item.getVerticalName())
</td>
私が発見した問題は、元のモデルで結合を指定したにもかかわらず (モデルがビューに渡される前に垂直プロパティに値が読み込まれていることを確認できました)、 getVerticalName メソッドを使用すると、Linq は自動的にデータベースに再度アクセスして垂直をロードし、垂直名にアクセスできるようにします。これは非常に非効率的です。なぜなら、クライアントごとに別々の db 呼び出しを行って、垂直方向の情報を取得するだけだからです。
ここで何が欠けていますか?プロパティが既にバインドされていて、それを取得するためにデータベースにアクセスしないことを LINQ が認識すべきではありませんか、それとも、モデルに情報が既に存在することを LINQ に伝えるために指定する必要があるものはありますか?