linq クエリに sql クエリにマップされない関数がある場合は、最初に .AsEnumerable() を呼び出す必要があることを理解しています。
var model = _service.GetQuery
.Where(data => data.SomeFlag == true)
.Select(data => new { Foo = CalculateFoo(data.Bar); });
linq to sql では実行できませんが、AsEnumerable() を追加することで、代わりに .Select() 句を linq でオブジェクトに実行させることができます。
var model = _service.GetQuery
.Where(data => data.SomeFlag == true)
.AsEnumerable()
.Select(data => new { Foo = CalculateFoo(data.Bar); });
しかし、データセットが非常に大きい場合、AsEnumerable はページングにどのような影響を与えるでしょうか? 私が言うなら:
var page = model.Skip((page > 0 ? page - 1 : 0) * rows).Take(rows);
model は IQueryable ではなく IEnumerable になったため、model.Skip().Take() と言うと、スキップして取得する前に、まずデータベースからデータセット全体をロードする必要がありますか? (これはページングの目的を無効にします)
編集:質問は一般的に書かれました-これらは具体的な詳細です:
私はページングを制御できません。モデルを生成し、それをグリッド コンポーネント (この場合は DevExpress ですが、任意のグリッドにすることができます) に渡します。ページング コマンドを発行するのはグリッド コンポーネントです。ここでは、AsEnumerable() の前に .Skip().Take() を使用するソリューションは使用できません。
したがって、このモデルをグリッドに渡すことができる必要があり、同時にモデルが遅延実行を使用していることを確認する必要があります。
var model = _service.GetQuery
.Where(data => data.SomeFlag == true)
.Select(data => new {
data.Id,
data.Customer.Code,
data.Customer.Name,
// etc, select a few other properties
Foo = CalculateFoo(data.Bar);
});
だから今、私は岩と難しい場所の問題を抱えています:
- そのモデルをグリッドに渡すと、linq to sql は CalculateFoo() を実行できないため、現在のページを表示するときに例外がスローされます。
- AsEnumerable() を追加すると、グリッドは現在のページを表示できますが、そのためにはデータセット全体をロードする必要があります (200 行を表示するためだけに何千行もロードします)。
- モデルから Foo 列を除外すると、実行が再び延期されますが、グリッドには列がありません