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

C# LINQ to Entities查询以展平结果并选择和分组所需信息,c#,.net,linq,C#,.net,Linq,我有三张小桌子,如下所示: 现在我想要一些关于每个房间一天订购多少餐的报告 我在自助餐厅客户表中有ROOM属性(名为AULA) 我想列出每个房间订购了多少OrderedItems。如果该房间中有MenuType==额外订购的OrderedItems,则列出所有订购该房间的客户(姓名+姓氏)。大概是这样的: ROOM 1 PASTA: 12 STEAK: 13 SALAD: 12 EXTRAS:

我有三张小桌子,如下所示:

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

我在自助餐厅客户表中有ROOM属性(名为AULA

我想列出每个房间订购了多少OrderedItems。如果该房间中有MenuType==额外订购的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,我没有找到。现在,我必须浏览列表,阅读每件物品的属性,并按房间和额外物品等进行排列

{
“房间”:“奥拉2号”,
“意大利比萨饼”:“意大利比萨饼”,
“类型”:“额外”,
“客户名称”:“Riki Gervais”
}, 
{
“房间”:“奥拉3号”,
“意大利面”:“意大利面”,
“类型”:“额外”,
“客户名称”:“John M Meyer”
},
{
“房间”:“奥拉3号”,
“MealItem”:“香肠”,
“类型”:“内部”,
“客户名称”:“史蒂夫·奥德瓦耶”
},
{
“房间”:“奥拉3号”,
“意大利面”:“意大利面”,
“类型”:“额外”,
“客户名称”:“艾伦·帕克”
},
{
“房间”:“奥拉6号”,
“MealItem”:“Riggatoni”,
“类型”:“外部”,
“客户名称”:“John Susack”
}
您可以:

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

或者你可以选择多个,然后用同样的方法分组

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

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();
        }
var cafOrders=新的cafOrders
{
OrderedItems=新列表
{
新订单编辑
{
caffclient=新的自助餐厅客户{AULA=“AULA 2”,Name=“Riki”,Name=“Gervais”},
Name=“意大利比萨饼”,
MenuType=“额外”
},
新订单编辑
{
CaffClient=新的自助餐厅客户{AULA=“AULA 3”,Name=“John”,Name=“M Meyer”},
Name=“意大利面”,
MenuType=“额外”
},
新订单编辑
{
CaffClient=新自助餐厅客户{AULA=“AULA 3”,Name=“Steve”,姓氏=“O'Dwayer”},
Name=“香肠”,
MenuType=“额外”
},
新订单编辑
{
CaffClient=新的自助餐厅客户{AULA=“AULA 3”,Name=“Allan”,Name=“Parker”},
Name=“意大利面”,
MenuType=“额外”
},
新订单编辑
{
CaffClient=新的自助餐厅客户{AULA=“AULA 6”,Name=“John”,姓氏=“Susack”},
Name=“Riggatoni”,
MenuType=“外部”
}
}
};
var orders=cafOrders.OrderedItems.GroupBy(o=>o.CafClient.AULA)
.选择(g=>new
{
Room=g.First().CafClient.AULA,
NumberOfRooms=g.Count(),
Clients=g.Where(x=>x.MenuType==“EXTRA”)。选择(e=>e.CafClient.Name),
MealItemToCount=g.GroupBy(m=>m.Name).ToDictionary(k=>k.First().Name,v=>v.Count())
})
.ToList();
}

制作一个你想要的类模式

    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; }
    }
更新

  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()
         });              
公共课餐
{
公共字符串名称{get;set;}
公共整数计数{get;set;}
}
公共教室
{
公共字符串名称{get;set;}
公共列表{get;set;}
公共列表附加项{get;set;}
}
var groupOrders=cafforders.GroupBy(x=>x.caffeetaclient.AULA)
.选择(x=>新房间
{
Name=x.Key,
膳食=x.SelectMany(y=>y.OrderedItems)
.Where(y=>y.MenuType!=“额外”)
.GroupBy(y=>y.Name)
.选择(z=>新餐
{
Name=z.键,
Count=z.Count()
}).ToList(),
Extras=x.SelectMany(y=>y.OrderedItems)
.其中(y=>y.MenuType==“额外”)
.GroupBy(y=>y.Name)
.选择(z=>new EXTRA
{
Name=z.键,
Count=z.Count(),
UserNames=z.GroupBy(k=>new{k.CafClient.Name,
k、 CafClient.name})
.选择(k=>新用户{
Count=k.Count(),
Name=k.Key.Name+k.Key.姓氏})
托利斯先生()
})托利斯先生()
});              

OrderedItems是订单上的集合导航属性。因此,如果我尝试上面的代码,它会给我以下错误:
调用_GroupBy_uu方法的键选择器类型在底层存储提供程序中是不可比较的。
糟糕的是,我忘了您没有在内存中执行此操作。让我想想在这种情况下我会怎么做……我也可以在内存中这样做,如果我可以处理匿名对象列表,每个对象都有{Room,MealItem,Type,ClientName}。运行我的方法时从服务器获得的列表。但同时我也不知道我的查询效率有多高。我正在学习:)这很有趣,但是这段代码不适合我,因为对象不一样。我将发布我的模型类的外观。我们使用的是LINQtoEntities,而不是内存中的,所以TODISCTIONAL不适用于LINQtoEntities。也不允许使用First()方法,但我想可以用FirstOrDefault()替换它好吧,这很有趣。这给我带来了一系列的结果。然而,我看到你在餐点上有一个“计数”属性
  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()
         });