如何过滤 IQueryable<T> 的嵌套项?
How can I filter nested items of IQueryable<T>?
我正在构建 Expression<Func<Project, bool>>
类型的表达式,其中 returns 来自数据库的正确 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>>
?如果没有,我有什么选择?
您应该能够使用 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);
}
我正在构建 Expression<Func<Project, bool>>
类型的表达式,其中 returns 来自数据库的正确 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>>
?如果没有,我有什么选择?
您应该能够使用 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);
}