【问题标题】:How can I filter nested items of IQueryable<T>?如何过滤 IQueryable<T> 的嵌套项?
【发布时间】:2023-04-08 07:09:01
【问题描述】:

我正在构建一个Expression&lt;Func&lt;Project, bool&gt;&gt; 类型的表达式,它会从数据库中返回正确的IQueryable&lt;Project&gt;IQueryable&lt;Project&gt; 有一个嵌套的 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&lt;Func&lt;SubProject, bool&gt;&gt; 添加到过滤器?如果没有,我还有什么选择?

【问题讨论】:

    标签: c# linq iqueryable


    【解决方案1】:

    您应该能够使用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);
        }
    

    【讨论】:

    • @Johnny5 我还没试过,但为什么?还有其他方法吗?
    猜你喜欢
    • 2012-11-20
    • 2020-12-22
    • 2012-01-09
    • 2011-02-09
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2017-06-07
    • 2022-01-08
    相关资源
    最近更新 更多