我正在构建一个类型为Expression<Func<Project, bool>>
的表达式,它从数据库中返回正确的IQueryable<Project>
。 IQueryable<Project>
有一个嵌套的SubProjects
集合,我也希望对其进行过滤。它看起来像这样
这可以通过一次调用数据库完成吗?
例如:
Expression<Func<Project, bool>> projectFilter = FilterEnabled();
projectFilter = projectFilter.And(GetProjectsByOrganization());
var projectData = GetProjectsAsQueryable(projectFilter); //returns correct projects
这就是我想做的事情:
Expression<Func<Project, bool>> projectFilter = FilterEnabled();
projectFilter = projectFilter.And(GetProjectsByOrganization())
.And(GetSubProjectsByStartDate());
var projectData = GetProjectsAsQueryable(projectFilter); //returns correct projects and the filtered sub projects by start date
GetProjectsByOrganization
如下
public Expression<Func<Project, bool>> GetProjectByOrganization()
{
var organizationIDs = new List<Guid>();
if (FilterCriteria.OrganiazaitonId != null)
organizationIDs = OrganizationRepository.GetParentAndChildrenOrganizationIds(FilterCriteria.OrganiazaitonId.Value).ToList();
//...
return prj => FilterCriteria.OrganiazaitonId == null || organizationIDs.Contains(prj.OrganizationID.Value);
}
如何在过滤器中添加Expression<Func<SubProject, bool>>
?如果不是我有什么替代品?
答案 0 :(得分:10)
您应该能够使用Expression.AndAlso
将所有3个表达式合并为一个新表达式。使用Expression.PropertyOrField
,您可以将您的项目作为参数传递给您的子项目:
static Expression<Func<Project, bool>> CombineFilterExpression(
Expression<Func<Project, bool>> firstProjectFilter,
Expression<Func<Project, bool>> secondProjectFilter,
Expression<Func<SubProject, bool>> subProjectFilter
)
{
//Create Project Parameter
var param = Expression.Parameter(typeof(Project));
//Create && Expression
var body = Expression.AndAlso(
Expression.Invoke(firstProjectFilter, param),
Expression.AndAlso( //Create second && Expression
Expression.Invoke(secondProjectFilter, param),
//Pass SubProject instead of Project
Expression.Invoke(subProjectFilter, Expression.PropertyOrField(param, nameof(Project.SubProject)))
)
);
//Make Lambda with Project parameter
return Expression.Lambda<Func<Project, bool>>(body, param);
}