将实体划分为组

时间:2014-02-16 14:58:04

标签: c# linq entity-framework

我有一个LINQ实体框架查询,它返回如下内容:

{Start: 1/1/2000T18:00:00, FirstName: John, LastName: Doe},
{Start: 1/1/2000T18:00:00, FirstName: Bob, LastName: Doe},
{Start: 1/1/2000T18:00:00, FirstName: Jack, LastName: Doe},

{Start: 1/1/2000T22:00:00, FirstName: John, LastName: Doe},
{Start: 1/1/2000T22:00:00, FirstName: Bob, LastName: Doe},
{Start: 1/1/2000T22:00:00, FirstName: Jack, LastName: Doe},

{Start: 2/1/2000T10:00:00, FirstName: John, LastName: Doe},
{Start: 2/1/2000T10:00:00, FirstName: Bob, LastName: Doe},
{Start: 2/1/2000T10:00:00, FirstName: Jack, LastName: Doe},

{Start: 2/1/2000T14:00:00, FirstName: John, LastName: Doe},
{Start: 2/1/2000T14:00:00, FirstName: Bob, LastName: Doe},
{Start: 2/1/2000T14:00:00, FirstName: Jack, LastName: Doe},
例如,人们在不同日子和不同时间的转变。

我想创建一个对象,其中班次分为几天和几小时,如下所示:

1/1/2000:
[
    18:00:00:
    [
        {FirstName: John, LastName: Doe},
        {FirstName: Bob, LastName: Doe},
        {FirstName: Jack, LastName: Doe}
    ]
]

等...

使用LINQ to实体是否有方便的方法?

谢谢!

3 个答案:

答案 0 :(得分:3)

您可以使用“分组依据”按多个属性进行分组,但首先需要提取“开始”的日期和时间部分。您可以按日期分组,然后按时间分组,或者语法更简单的方法是按两者分组,然后按时间对内部集合进行分组:

var x = from shift in Shifts
                    let date = EntityFunctions.TruncateTime(shift.Start)
                    let time = EntityFunctions.CreateTime(shift.Start.Hour, shift.Start.Minute, shift.Start.Second)
                    group shift by new { date, time } into groupedByDate
                    select new
                    {
                       Date = groupedByDate.Key.date,
                       ShiftsByTime = from g in groupedByDate group g by groupedByDate.Key.time
                    };

如果您不关心层次结构,也可以按{date,time}对进行分组:

  var x = from shift in Shifts
                let date = EntityFunctions.TruncateTime(shift.Start)
                let time = EntityFunctions.CreateTime(shift.Start.Hour, shift.Start.Minute, shift.Start.Second)
                group shift by new {date, time};

这是一个比上面第一个更详细但语义相同的查询。我检查了生成的SQL,它或多或少等价:

var x = from shift in Shifts
                let date = EntityFunctions.TruncateTime(shift.Start)
                group shift by date into groupedByDate
                select new
                       {
                           Date = groupedByDate.Key,
                           ShiftsByTime = from g in groupedByDate
                               let time = EntityFunctions.CreateTime(g.Start.Hour, g.Start.Minute, g.Start.Second)
                               group g by time
                       };

答案 1 :(得分:0)

尝试使用.Select和.GroupBy像这样:

var res = list.Select(x => new 
                        {
                            Person = x,
                            Date = x.Start.Date,
                            Time = x.Start.TimeOfDay
                        })
                .GroupBy(x => x.Date)
                .Select(personGroupByDate => new 
                {
                    Date = personGroupByDate.Key,
                    Persons = personGroupByDate
                        .Select(x => x.Person)
                        .GroupBy(x => x.Time)
                        .Select(person => new 
                        {
                            FirstName = person.FirstName,
                            LastName = person.LastName
                        }).ToList()
                }).ToList()

答案 2 :(得分:0)

您需要使用GroupBy来嵌套结果......

我发布了我的整个测试应用程序用于测试目的

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Web.Script.Serialization;

namespace ConsoleApplication1
{
    class Program
    {
        static void Main(string[] args)
        {
            var objs = new Shift[] {
                new Shift {Start= DateTime.Parse("1/1/2000 18:00:00"), FirstName= "John", LastName= "Doe"},
                new Shift {Start= DateTime.Parse("1/1/2000 18:00:00"), FirstName= "Bob", LastName= "Doe"},
                new Shift {Start= DateTime.Parse("1/1/2000 18:00:00"), FirstName= "Jack", LastName= "Doe"},
                new Shift {Start= DateTime.Parse("1/1/2000 22:00:00"), FirstName= "John", LastName= "Doe"},
                new Shift {Start= DateTime.Parse("1/1/2000 22:00:00"), FirstName= "Bob", LastName= "Doe"},
                new Shift {Start= DateTime.Parse("1/1/2000 22:00:00"), FirstName= "Jack", LastName= "Doe"},
                new Shift {Start= DateTime.Parse("2/1/2000 10:00:00"), FirstName= "John", LastName= "Doe"},
                new Shift {Start= DateTime.Parse("2/1/2000 10:00:00"), FirstName= "Bob", LastName= "Doe"},
                new Shift {Start= DateTime.Parse("2/1/2000 10:00:00"), FirstName= "Jack", LastName= "Doe"},
                new Shift {Start= DateTime.Parse("2/1/2000 14:00:00"), FirstName= "John", LastName= "Doe"},
                new Shift {Start= DateTime.Parse("2/1/2000 14:00:00"), FirstName= "Bob", LastName= "Doe"},
                new Shift {Start= DateTime.Parse("2/1/2000 14:00:00"), FirstName= "Jack", LastName= "Doe"}
            };

            var dates = objs
                .GroupBy(i => i.Start.Date)
                .Select(i => new
                {
                    Date = i.Key,
                    Times = i.GroupBy(s => s.Start.TimeOfDay).Select(s => new
                    {
                        Time = s.Key,
                        People = s.Select(ss => new { ss.FirstName, ss.LastName })
                    })
                });

            Console.ReadLine();
        }
    }

    class Shift
    {
        public DateTime Start { get; set; }
        public string FirstName { get; set; }
        public string LastName { get; set; }
    }
}