Linq表达式用于过滤集合集合?

时间:2010-12-21 22:25:41

标签: linq entity-framework

我希望对于擅长Linq的人来说,这将是一个相当简单的问题。我正努力为以下内容提出正确的Linq表达方式。我能够通过破解来获得结果,但我确信有一个正确而简单的Linq方法可以做到这一点,我对Linq还不够好......

我有一个通过Entity Framework访问的数据库。它有许多任务。每个任务都有一个TimeSegments集合。 TimeSegments具有日期和员工属性。

我想要的是能够获得某个员工和某个月的任务以及同一个月和员工的每项任务的时间段。

同样,任务本身不具有月份或日期信息,但它们通过与每个任务相关联的时间段来完成。

非常简化它看起来像这样:

    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 个答案:

答案 0 :(得分:2)

这是我能想到的最简单的事情:

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.TimeSegmentTimeSegment.Task

LINQ查询的诀窍通常是从正确的集合开始。在这种情况下,理想的起点是TimeSegments

PS。我不确定Date.Month == month是否真的可以与EF一起使用,但我认为它会(使用EF 4.0)。

<小时/> 的更新

  

你能说明如何扩展它吗?   查询并获取任务   特别是客户?

我不确定你的意思,但你可以像这样过滤掉之前的可查询:

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

我可以将返回类型作为列表   具有TimeSegments列表的任务   如果我在方法中有这个?

同样,不确定你到底想要什么,但是如果你想要两个没有关系的单独列表,你可以这样做:

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 :(得分:1)

  

我想要的是能够获得   某个员工的任务和   某个月和时间段   同一个月的每项任务   雇员。

这将从模型实例中选择任务,其中任务至少有一个时间段,在请求的员工的请求月份中(未经测试):

Model model = new Model();
tasks = model.Tasks.Where(t => t.TimeSegments.Any(ts => ts.Employee.Id = requestedId && Convert.ToDate(ts.Date).Month == requestedMonth));