实体框架 - .Select()中的动态过滤器

时间:2012-01-17 20:52:01

标签: c# entity-framework-4.1

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

在这种情况下,我正在使用项目和任务。

我有一个允许用户选择项目的表单,并且可以选择可以在项目中分配任务的人员。

在我的Project 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的所有项目。

再说一次,我怎样才能获得所有项目,但只能分配给约翰的任务?

谢谢!

2 个答案:

答案 0 :(得分:1)

您可以像这样定义'已分配'过滤器:

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
        })
});

答案 1 :(得分:1)

根据我的理解,您有一种动态过滤功能,具体取决于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
    })
});