面倒な LINQ-to-SQL データ レイヤーをエンティティ フレームワークでリファクタリングしようとしています。モデルの背後にあるデータベース スキーマは大きく、典型的なクエリには 20 から 30 のインクルードが含まれる場合があります。EF は、このようなクエリに対して大量の SQL ステートメントを生成します。これまでで最大のものは 4,000 行ですが、それでもタイムリーに実行されるため、問題にはなりません。
問題は、EF がクエリを生成するのに最大 4 秒または 5 秒かかるということです。これを克服するために、CompileQuery を使用しました。問題は、既存の L2S データレイヤーに、ユーザー入力に応じてクエリに適用できるフィルターが多数あることです。これらのフィルターの単一の値は、実行時に設定する必要があります。
以下のコードは、最初の静的値がクエリにコンパイルされるため機能しませんが、私がやろうとしていることを示しています。
public static class DataLayer
{
static Func<MyEntities, int, IQueryable<Prescription>> compiledQuery;
static int? FilterHpID;
static Expression<Func<Prescription, bool>> filter1 = x => (FilterHpID == null || x.Prescriber.HPID == FilterHpID);
static DateTime? FilterDateTime;
static Expression<Func<Prescription, bool>> filter2 = x => (FilterDateTime == null || x.DateTimeDispensed > FilterDateTime);
public static List<Prescription> Get(int patientID, int? hpID, DateTime? dispensed)
{
FilterHpID = hpID;
FilterDateTime = dispensed;
if (compiledQuery == null)
{
compiledQuery = System.Data.Objects.CompiledQuery.Compile((MyEntities entities, int id) =>
(from pre in entities.Prescription
where pre.PatientID == id
select pre)
.Where(filter1)
.Where(filter2));
}
using (MyEntities entities = new MyEntities())
{
return compiledQuery(entities, patientID).ToList();
}
}
}
コンパイルされたクエリにフィルター式を含め、クエリの実行時にフィルター式に値を設定できる方法はありますか?