リスト/ToList が多いのはなぜですか? IEnumerable/IQueryable の何が問題になっていますか?
var eventi = (from Evento ae in new Eventi()
select ae);
if (strNome != "")
{
eventi = eventi.Where(e => e.Titolo.ToLower().Contains(strNome.ToLower()) && e.Titolo != "");
}
if (strComune != "")
{
eventi = eventi.Where(e => e.Comune != null && e.IDComune == strComune);
}
if (strMesi != "")
{
eventi = eventi.Where(e => MesiSelezionati.Contains(DateTime.Parse(e.DataEvento).Month.ToString()));
}
// if you do need a list, then do so right at the end
var results = eventi.ToList();
編集:Caesayのいくつかの原則を明確にする
Caesay さん、時間を割いて実装をテストし、遅延読み込みが意図したとおりに動作することを確認していただきありがとうございます。多くの称賛!
上記のアプローチが実行時に最適化されているのに対し、コンパイル時に最適化されているというコメントに同意しない理由を説明したかったのです。
上記のアプローチは、より適切な説明がないため、意図したアプローチです。これは、eventiへの割り当てが、IEnumerable/IQueryable のソースに式を正しく追加しているためです。
あなたのアプローチは、 Func(Of T, TResult)がSelect、Whereなどの拡張機能に渡されることを期待する、Linq to Entities などの特定のプロバイダーによってのみサポートされています。Entity Framework や Linq to Sql プロバイダーなどの多くのプロバイダーは、IEnumerableを実装するIQueryableを提供します。ただし、ここでの違いは、IQueryableのSelect、Whereなどは、 Expression(Of Func(Of T, TResult))を渡すことを想定していることです。
そのような場合、Expression は複数行のラムダをサポートしていないため、コードは期待どおりに (または少なくとも私が期待するようには) 動作しませんが、コンパイラはステートメントを正しく解釈して Expression> にコンパイルします。
簡単な例として:
public void Test<T1, T2>(System.Linq.Expressions.Expression<Func<T1, T2>> arg)
{
throw new NotImplementedException();
}
public void Test()
{
Test((string x) => x.ToLower());
Test((string x) =>
{
return x.ToLower();
});
}
上記の例では、最初の式はまったく問題ありません。あなたの例に大まかに基づいている2番目は、例外で失敗します:
A lambda expression with a statement body cannot be converted to an expression tree
コンパイラは、ステートメントを、IEnumerable でサポートされていることを認識しているFuncとして認識する場合があります。その結果、データベースへのクエリには Where 式が含まれず、データ ソース全体が返されます。データ ソースがインメモリになると、IEnumerable Where 句が適用されます。個人的には、必要以上のデータを返すために帯域幅を浪費しないように、これらの種類のものをデータベースに渡すことを非常に好みます。ケース) インメモリで行うよりも優れています。
それが理にかなっていて、あなたに役立つことを願っていますか?