Я пытаюсь провести рефакторинг громоздкого слоя данных LINQ-to-SQL с помощью структуры сущностей.Схема базы данных за моделью большая, и типичный запрос может содержать от 20 до 30 включений.EF генерирует массивные операторы SQL для таких запросов, самые большие из которых до сих пор были 4k строк, но они по-прежнему выполняются своевременно, так что это не проблема.
Проблема в том, что 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();
}
}
}
Есть ли способ, которым я могу включитьмои выражения фильтра в скомпилированном запросе И возможность устанавливать значения в выражениях фильтра при выполнении запроса?