实体框架-.Select()中的动态筛选器

本文关键字:动态 筛选 框架 Select 实体 | 更新日期: 2023-09-27 18:20:30

我正在使用投影来用数据填充ViewModels。

在这种情况下,我正在处理项目和任务。

我有一个表单,允许用户选择一个项目,并选择性地选择项目中可能分配任务的人。

在我的项目ViewModel中,我有用于任务的ViewModel:

public IEnumerable<TaskVM> TaskVM { get; set; }

我过滤查询如下:

var query = db.Projects.AsQueryable();
if (filterProjectId)
{
    query = query.Where(p => p.ProjectId == ProjectId); 
}
if (filterAssignedTo)
{
    query = query.Where(p => p.Tasks.Any(t => t.AssignedTo == "John")); 
}

问题:以上将返回所有分配给John的任务的项目,但也将返回分配给Fred的任务。我的问题是:我如何才能得到所有的项目,但只有分配给约翰的任务?

我知道我能做到:

var resultList = query.Select(p => new ProjectVM
{
    ProjectId = p.ProjectId,
    ProjectName = p.ProjectName,
    TaskVM = p.Tasks.Where(t => t.AssignedTo == "John").OrderByDescending(t => t.TaskName).Select(t => new TaskVM
    {
        TaskId = t.TaskId,
        TaskName = t.TaskName,
        AssignedTo = t.AssignedTo
    })
});

但是,我不知道我是否需要过滤约翰。用户可能想要projectId为的所有项目。

再说一遍,我怎么能得到所有的项目,但只有分配给约翰的任务?

谢谢!

实体框架-.Select()中的动态筛选器

据我所知,您有一种依赖于filterProjectIdfilterAssignedTo布尔值的动态过滤。

以下是您可以做的:

var resultList = db.Projects.Where(z => !filterProjectId || z.ProjectId == MyProjectId).Select(p => new ProjectVM
{
    ProjectId = p.ProjectId,
    ProjectName = p.ProjectName,
    TaskVM = p.Tasks.Where(t => !filterAssignedTo || t.AssignedTo == "John").OrderByDescending(t => t.TaskName).Select(t => new TaskVM
    {
        TaskId = t.TaskId,
        TaskName = t.TaskName,
        AssignedTo = t.AssignedTo
    })
});

您可以这样定义"分配给"过滤器:

Expression<Func<Project, bool>> assignedToFilter;
if (filterAssignedTo)
{
    assignedToFilter = p => p.Tasks.Any(t => t.AssignedTo == "John");
}
else
{
    assignedToFilter = p => true;
}

然后像这样使用:

var resultList = query.Where(assignedToFilter).Select(p => new ProjectVM
{
    ProjectId = p.ProjectId,
    ProjectName = p.ProjectName,
    TaskVM = p.Tasks
        .Where(assignedToFilter)
        .OrderByDescending(t => t.TaskName)
        .Select(t => new TaskVM
        {
            TaskId = t.TaskId,
            TaskName = t.TaskName,
            AssignedTo = t.AssignedTo
        })
});