我正在尝试使用实体框架重构繁琐的 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();
}
}
}
有什么方法可以在编译的查询中包含我的过滤器表达式,并且能够在执行查询时在过滤器表达式上设置值?