我正在根据用户定义的过滤条件创建一个报告来列出我的数据库中的人员。因此,例如,我可以按姓名、年龄等进行过滤。
var people = db.People.AsQueryable();
if (filterByName)
people = people.Where(p => p.LastName.Contains(nameFilter));
if (filterByAge)
people = people.Where(p => p.Age == age);
现在,筛选标准之一是显示未接种所需疫苗的人。我有表Immunization
和PersonImmunization
(在 上具有唯一索引PersonID, ImmunizationID
)。如果某人缺少任何PersonImmunization
记录,或者如果他们接受的剂量数量低于要求,则应包括在内,否则不包括在内。
如果我正在编写 SQL 查询,它将是:
select p.*
from Person p
cross join Immunization i
left join PersonImmunization pi
on pi.PersonID = p.ID and pi.ImmunizationID = i.ID
where pi.ID is null or pi.Doses < i.RequiredDoses;
现在为了使这部分成为我的 where 子句,我需要使用Expression
谓词来表达这一点:
if (filterByImmunizations) {
Expression<Func<Person, bool>> nonCompliantImmunization =
person => <now what?>;
people = people.Where(nonCompliantImmunization);
}
我遇到的第一个问题是如何在表达式中使用免疫。然后,一旦我有了它,我怀疑找到不合规的人可能会更直接,但如果你可以在你的答案中包含它,我将非常感激!
编辑: 我被要求解释为什么我如此准备使用Expression<Func<Person, bool>>
. 原因是我已经构建了一个完整的通用框架,用于在几种不同的上下文中编写复杂的、用户定义的查询。为了让您了解引擎内部的内容,以下是我的基类内部内容的片段:
public abstract class QueryBuilder<T> where T : EntityObject {
public static IQueryable<T> FilterQuery(IQueryable<T> query, IEnumerable<QueryConditionLite> filters, bool anyConditionSufficient) {
...
}
protected Expression<Func<TBase, bool>> GetPredicate(Expression<Func<TBase, double>> expression, IQueryCondition condition) {
...
}
}
然后我有一个PersonQueryBuilder : QueryBuilder<Person>
,在其中我想创建一个过滤器,显示不符合免疫要求的人。我想你会同意查询语法不会削减它。