Выражение Linq для отфильтрованной коллекции коллекций? - PullRequest
0 голосов
/ 22 декабря 2010

Я надеюсь, что это будет довольно простой вопрос для тех, кто хорош в Linq.Я изо всех сил пытаюсь придумать правильное выражение Linq для следующего.Я могу что-то взломать, чтобы получить результаты, но я уверен, что есть правильный и простой способ сделать это на Linq, я просто недостаточно хорош в Linq ...

У меня естьдоступ к базе данных через Entity Framework.У него есть ряд задач.Каждая задача имеет коллекцию временных сегментов.Временные сегменты имеют свойства «Дата» и «Сотрудник».

Я хочу, чтобы у меня была возможность получать задачи для определенного сотрудника и определенного месяца, а также временные сегменты для каждой задачи для того же месяца и сотрудника.

Опять же, сами по себе задачи не содержат информации о месяце и дате, но они связаны с сегментами времени, связанными с каждой задачей.

Очень упрощенно это выглядит примерно так:

    public class Model //Simplified representation of the Entity Framework model
    {
        public List<Task> Tasks { get; set; }
    }

    public class Task
    {
        public int Id { get; set; }
        public List<TimeSegment> TimeSegments { get; set; }
        public Customer Customer { get; set; }
    }

    public class TimeSegment
    {
        public int Id { get; set; }
        public string Date { get; set; }
        public Employee Employee { get; set; }
    }

    public class Employee
    {
        public int Id { get; set; }
        public string Name { get; set; }
    }

Так как мне сделать это как можно проще с Linq?Т.е. задачи и связанные с ними временные сегменты на определенный месяц и сотрудника.Я также хотел бы иметь возможность получить его от клиента BTW ...

Ответы [ 2 ]

2 голосов
/ 22 декабря 2010

Это самое простое, что я могу придумать:

var tasksWithSegments =
    from segment in model.TimeSegments
    where segment.Date.Month == month
    where segment.Employee.Id == employeeId
    group segment by segment.Task into result
    select new
    {
        Task = result.Key,
        TimeSegments = result.ToArray()
    };

Обратите внимание, что вам может потребоваться добавить некоторые свойства в вашу модель, например Model.TimeSegment и TimeSegment.Task.

Трюк с LINQ-запросами часто заключается в том, чтобы начать с правильной коллекции.В этом случае идеальной отправной точкой является TimeSegments.

пс.Я не уверен, будет ли Date.Month == month действительно работать с EF, но я думаю, что это будет работать (с EF 4.0, который есть).

Обновление:

Не могли бы вы показать, как расширить этот запрос и получить задачи для конкретного клиента?

Я не уверенчто вы имеете в виду, но вы можете, например, отфильтровать предыдущий запрос, как это:

var tasksWithSegmentsForCustomers =
    from taskWithSegments in tasksWithSegments
    where taskWithSegments.Task.Customer.Id == customerId
    select taskWithSegments;

Могу ли я получить тип возвращаемого значения в виде списка задач со списком TimeSegment, если у меня этометод?

Опять же, вы не уверены, чего именно хотите, но если вам нужны два отдельных списка, которые не имеют отношения, вы можете сделать это:

List<Task> tasks = (
    from taskWithSegments in tasksWithSegments
    select taskWithSegments.Task).ToList();

List<TimeSegments> segments = (
    from taskWithSegments in tasksWithSegments
    from segment in taskWithSegments.Segments
    select segment).ToList();

Конечно,если это то, что вам нужно, то может быть проще переписать исходный запрос примерно так:

List<TimeSegment> segments = (
    from segment in model.TimeSegments
    where segment.Date.Month == month
    where segment.Employee.Id == employeeId
    select segment).ToList();

List<Task> allTasks =
    segments.Select(s => s.Task).Distinct().ToList();

Как только вы научитесь писать запросы LINQ, вы не сможете вернуться назад.писать операторы SQL или устаревшие операторы foreach.

Подумайте, LINQ !!!

1 голос
/ 22 декабря 2010

То, что я хочу, - это иметь возможность получить задачи для определенного сотрудника и определенный месяц и временные сегменты для каждая задача на тот же месяц и работник.

Это выберет задачи из экземпляра модели, где задача имеет хотя бы один временной сегмент, который в запрошенном месяце для запрошенного сотрудника (не проверено):

Model model = new Model();
tasks = model.Tasks.Where(t => t.TimeSegments.Any(ts => ts.Employee.Id = requestedId && Convert.ToDate(ts.Date).Month == requestedMonth));
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...