LINQ to Entities查询以展平结果并选择和分组所需信息

时间:2017-05-04 12:27:03

标签: c# .net linq

我有三个小表,如下所示:

enter image description here

现在我想得到一些关于每个房间每天订购多少餐食的报告。

我在CafeteriaClients表中有ROOM属性(名为 AULA )。

我想列出每个ROOM订购的OrderedItems数量。如果在该ROOM中订购了MenuType == EXTRA的OrderedItems,则列出所有订购它的客户(姓名+姓氏)。像这样:

ROOM 1
          PASTA: 12
          STEAK: 13
          SALAD: 12
           EXTRAS:
             TIRAMISU: 12
                 UserName 1
                 UserName 2
                 ....
                 UserName 12
             MACEDONIA: 2
                 UserName 3
                 UserName 4
 ROOM 2
          .....
          ......

到目前为止,我所做的是:

    [HttpGet]
    public IHttpActionResult GetOrdersForRooms()
    {
        using (var ctx = new CafeteriaContext())
        {
            var Date = DateTime.Today;

            var orders = ctx.CafOrders.Where(d => d.Date == Date)
                .SelectMany(o => o.OrderedItems
                .Select(c => new { 
                            Room = c.CafClient.AULA, 
                            MealItem = c.Name, 
                            Type = c.MenuType, 
                            ClientName = c.CafClient.Name }))
                 .ToList();



            return Ok(orders);
        }           
    }

这给我带来了以下形式的结果,这是好的,但我确信LINQ还有更多,并且必须有一种方法可以更好地使用我找不到的SelectMany或GroupBy。现在我必须查看列表,阅读每个对象的属性,并按ROOMS和EXTRAS等排列它们。



    {
      "Room": "Aula 2",
      "MealItem": "Pizza Italiana",
      "Type": "EXTRA",
      "ClientName": "Riki Gervais"
    }, 
    {
      "Room": "Aula 3",
      "MealItem": "Spaghetti",
      "Type": "EXTRA",
      "ClientName": "John M Meyer"
    },
    {
      "Room": "Aula 3",
      "MealItem": "Sausage",
      "Type": "INTERNAL",
      "ClientName": "Steve O'Dwayer"
  },
  {
      "Room": "Aula 3",
      "MealItem": "Pasta",
      "Type": "EXTRA",
      "ClientName": "Allan Parker"
  },
  {
      "Room": "Aula 6",
      "MealItem": "Riggatoni",
      "Type": "EXTERNAL",
      "ClientName": "John Susack"
  }




然后我将这些结果过滤掉并按照所需的形式排列,但我想知道是否可以从一开始就使用LINQ to Entities做更多的事情,并获得没有冗余的信息。例如,每个ROOMS直接对结果进行分组。

    [Table("CafOrders")]
public class CafOrders
{
    [Key]
    [Required]
    public int Id { get; set; }

    [Required]
    public DateTime Date { get; set; }

    public string Note { get; set; }

    public decimal Total { get; set; }

    public int ClientId { get; set; }

    [ForeignKey("ClientId")]
    public CafeteriaClients CafeteriaClient { get; set; }

    public ICollection<OrderedItems> OrderedItems { get; set; }

}



   [Table("CafeteriaClients")]
public class CafeteriaClients
{
    [Key]
    [Required]
    public int Id { get; set; }

    [Required]
    public string Name { get; set; }

    [Required]
    public string Surname { get; set; }

    public string AULA { get; set; }

    public string MATR { get; set; }

    [Required]
    public string CustomerType { get; set; }

    public string GRUPPO { get; set; }


    public ICollection<OrderedItems> OrderedItems { get; set; }
}




    public class OrderedItems
{

    public int Id { get; set; }

    public int OrderId { get; set; }

    public int ClientId { get; set; }

    public string Name { get; set; }

    public decimal Price { get; set; }

    public string Description { get; set; }

    public string MenuType { get; set; }

    [ForeignKey("OrderId")]
    public CafOrders CafOrder { get; set; }

    [ForeignKey("ClientId")]
    public CafeteriaClients CafClient { get; set; }

}

3 个答案:

答案 0 :(得分:1)

你可以:

var orders = ctx.CafOrders.Where(d => d.Date == Date)
            .GroupBy(n => new { n.OrderedItems, n.(any other field you want to group}).Select(n => new { })

或者您可以使用select many然后以相同的方式分组...

答案 1 :(得分:1)

制作一个你想要的课程模式

    public class Room
    {
        public string Name { get; set; }

        public List<Meal> Meals { get; set; }
    }

    public class Meal
    {
        public string Name { get; set; }
        public int Count { get; set; }

        public List<EXTRA> Extras { get; set; }
     }

    public class EXTRA
    {
        public string Name { get; set; }

        public List<User> UserNames { get; set; }
    }

    public class User
    {
        public string Name { get; set; }

        public int Count { get; set; }
    }

然后尝试这个......

  var groupOrders = CafOrders.GroupBy(x => x.CafeteriaClient.AULA)
        .Select(x => new Room
         {
             Name = x.Key,
             Meals = x.SelectMany(y => y.OrderedItems)
                      .GroupBy(y => y.Name)
                      .Select(z => new Meal
         {
           Name = z.Key,
           Count = z.Count(),
           Extras = z.Where(t => t.MenuType == "EXTRA")
                     .GroupBy(t => t.Name)
                     .Select(t => new EXTRA
         {
            Name = t.Key,
            UserNames = t.GroupBy(k => new { k.CafClient.Name, 
                                             k.CafClient.Surname 
            })
            .Select(k => new User {
            Name = k.Key.Name + k.Key.Surname, 
             Count = k.Count() }).ToList()
            }).ToList()
           }).ToList()
         });

更新

  public class Meal
  {
        public string Name { get; set; }
        public int Count { get; set; }
  }

 public class Room
 {
        public string Name { get; set; }

        public List<Meal> Meals { get; set; }

        public List<EXTRA> Extras { get; set; }

  }

   var groupOrders = CafOrders.GroupBy(x => x.CafeteriaClient.AULA)
        .Select(x => new Room
         {
             Name = x.Key,
             Meals = x.SelectMany(y => y.OrderedItems)
                      .Where(y => y.MenuType != "EXTRA")
                      .GroupBy(y => y.Name)
                      .Select(z => new Meal
                       {
                           Name = z.Key,
                           Count = z.Count()
                       }).ToList(),
             Extras = x.SelectMany(y => y.OrderedItems)
                      .Where(y => y.MenuType == "EXTRA")
                      .GroupBy(y => y.Name)
                      .Select(z => new EXTRA
                      {
                          Name = z.Key,
                          Count = z.Count(),
                          UserNames = z.GroupBy(k => new { k.CafClient.Name, 
                                                           k.CafClient.Surname })
                                       .Select(k => new User {
                                           Count = k.Count(), 
                                           Name = k.Key.Name + k.Key.Surname })
                                         .ToList()

                      }).ToList()
         });              

答案 2 :(得分:0)

我根据您的数据结构更改了答案:

var cafOrders = new CafOrders
{
    OrderedItems = new List<OrderedItems>
    {
        new OrderedItems
        {
            CafClient = new CafeteriaClients { AULA = "Aula 2", Name = "Riki ", Surname = "Gervais" },
            Name = "Pizza Italiana",
            MenuType = "EXTRA"
        },
        new OrderedItems
        {
            CafClient = new CafeteriaClients { AULA = "Aula 3", Name = "John ", Surname = "M Meyer" },
            Name = "Spaghetti",
            MenuType = "EXTRA"
        },
        new OrderedItems
        {
            CafClient = new CafeteriaClients { AULA = "Aula 3", Name = "Steve", Surname = "O'Dwayer" },
            Name = "Sausage",
            MenuType = "EXTRA"
        },
        new OrderedItems
        {
            CafClient = new CafeteriaClients { AULA = "Aula 3", Name = "Allan", Surname = "Parker" },
            Name = "Pasta",
            MenuType = "EXTRA"
        },
        new OrderedItems
        {
            CafClient = new CafeteriaClients { AULA = "Aula 6", Name = "John", Surname = "Susack" },
            Name = "Riggatoni",
            MenuType = "EXTERNAL"
        }
    }
};

var orders = cafOrders.OrderedItems.GroupBy(o => o.CafClient.AULA)
            .Select(g => new
            {
                Room = g.First().CafClient.AULA,
                NumberOfRooms = g.Count(),
                Clients = g.Where(x => x.MenuType == "EXTRA").Select(e => e.CafClient.Name),
                MealItemToCount = g.GroupBy(m => m.Name).ToDictionary(k => k.First().Name, v => v.Count())
            })
            .ToList();
        }