Entity Framework - Динамический фильтр в .Select () - PullRequest
0 голосов
/ 18 января 2012

Я использую проекцию для заполнения 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")); 
}

Вопрос: Вышеприведенное вернет все проекты, у которых есть какие-либо задачи, назначенные Джону, но также вернет задачи, назначенные Фреду. У меня такой вопрос: как я могу получить все проекты, но ТОЛЬКО задачи, назначенные Джону?

Я знаю, что могу сделать это:

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

Но я не знаю, нужно ли мне фильтровать Джона. Пользователь может захотеть ВСЕ проекты с идентификатором проекта.

Итак, еще раз, как я могу получить все проекты, но ТОЛЬКО задачи, назначенные Джону?

Спасибо!

Ответы [ 2 ]

1 голос
/ 18 января 2012

Насколько я понимаю, у вас есть своего рода динамическая фильтрация в зависимости от логических значений filterProjectId и filterAssignedTo.

Вот что вы можете сделать:

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
    })
});
1 голос
/ 18 января 2012

Вы можете определить фильтр «назначенный» следующим образом:

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
        })
});
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...