Entity framework core net core 3.1中的分组

Entity framework core net core 3.1中的分组,entity-framework-core,Entity Framework Core,我尝试按2个字段分组,然后计算每个状态的行数。 我正在使用.NETCore3.1和EF的最新版本 我得到一个错误:无法翻译LINQ表达式。或者以可以翻译的形式重写查询 到目前为止我调查的是,当我摆脱谓词 y.Count(x=>x.Status==“新建”) 只需离开y.Count()就可以了 Orders集合只是一个模拟的对象列表,在我的真实应用程序中,它是sql server中的一个表 //Rextester.Program.Main is the entry point for your c

我尝试按2个字段分组,然后计算每个状态的行数。 我正在使用.NETCore3.1和EF的最新版本

我得到一个错误:无法翻译LINQ表达式。或者以可以翻译的形式重写查询

到目前为止我调查的是,当我摆脱谓词 y.Count(x=>x.Status==“新建”) 只需离开y.Count()就可以了

Orders集合只是一个模拟的对象列表,在我的真实应用程序中,它是sql server中的一个表

//Rextester.Program.Main is the entry point for your code. Don't change it.
//Microsoft (R) Visual C# Compiler version 2.9.0.63208 (958f2354)

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text.RegularExpressions;

namespace Rextester
{
    public class Program
    {
        public static void Main(string[] args)
        {
            var orders = new List<Order>();
            orders.Add(new Order(){Year = 2020, Status = "New"});
            orders.Add(new Order(){Year = 2020, Status = "New"});
            orders.Add(new Order(){Year = 2020, Status = "Canceled"});
            orders.Add(new Order(){Year = 2020, Status = "Shipped"});            

            
            var result = await orders
                .GroupBy(x=> new {x.Year, x.Status})
                .Select(y => new 
                {   
                    Year = y.Key.Year,
                    NewCount = y.Count(x=>x.Status == "New"),
                    CanceledCount = y.Count(x=>x.Status == "Canceled"),
                    ShippedCount = y.Count(x=>x.Status == "Shipped")                          
                }).ToListAsync();
        }
    }
    public class Order
    {
        public int Year {get;set;}
        public string Status {get;set;}
    }
}
//Rextester.Program.Main是代码的入口点。不要改变它。
//Microsoft(R)Visual C#编译器版本2.9.0.63208(958f2354)
使用制度;
使用System.Collections.Generic;
使用System.Linq;
使用System.Text.RegularExpressions;
名称空间测试仪
{
公共课程
{
公共静态void Main(字符串[]args)
{
var orders=新列表();
添加(新订单(){Year=2020,Status=“new”});
添加(新订单(){Year=2020,Status=“new”});
添加(新订单(){Year=2020,Status=“cancelled”});
添加(新订单(){Year=2020,Status=“Shipped”});
var结果=等待订单
.GroupBy(x=>new{x.Year,x.Status})
.选择(y=>new
{   
年份=y.Key.Year,
NewCount=y.Count(x=>x.Status==“新建”),
CanceledCount=y.Count(x=>x.Status==“已取消”),
ShippedCount=y.Count(x=>x.Status==“已装运”)
}).ToListAsync();
}
}
公共阶级秩序
{
公共整数年{get;set;}
公共字符串状态{get;set;}
}
}
预期结果是:

年份:2020年,新计数:2

年份:2020,取消次数:1

年份:2020,船运数量:1

我做错了什么?如何更正此错误以获得所需的输出


编辑:这是我的游乐场

你能试试下面的吗。您已按年份和状态分组。状态是你的钥匙的一部分,所以你可以利用它为你的优势。然后使用
y.count()

使用系统;
使用System.Collections.Generic;
使用System.Linq;
公共课程
{
公共静态void Main(字符串[]args)
{
var orders=新列表();
添加(新订单(){Year=2020,Status=“new”});
添加(新订单(){Year=2020,Status=“new”});
添加(新订单(){Year=2020,Status=“cancelled”});
添加(新订单(){Year=2020,Status=“Shipped”});
var结果=订单
.GroupBy(x=>new{x.Year,x.Status})
.选择(y=>new
{   
年份=y.Key.Year,
状态=y.Key.Status,
Count=y.Count()
}).ToList();
foreach(结果中的var项目)
{
WriteLine(string.Format(“{0}{1}{2}”,item.Year,item.Status,item.Count));
}
}
}
公共阶级秩序
{
公共整数年{get;set;}
公共字符串状态{get;set;}
}

您发布的代码不会引发该异常。只有在使用EF Core进行无法转换为SQL的查询时才会引发该异常,这通常是因为它使用客户端函数来存储实际代码和实际异常。这是实际代码,唯一的更改是我调用injeted dbcontext而不是mocked list。顺便说一句,表达式
y.Count(x=>x.Status==“New”)
etc在SQL中毫无意义。GROUP BY和COUNT将返回单个计数值。再也没有可枚举的可筛选项了。无论如何,
状态
都是键的一部分。看起来您试图通过复制仅用于可枚举的代码来按结果“透视”组。这不适用于EF Core。30分钟前我回答了一个几乎相同的问题。使用
ToDictionary(g=>g.Key,g=>g.Count())将结果转换为
Dictionary
,并使用
列表检索单个键值,使用LINQ将永远不会抛出问题中发布的异常。发布的伪代码,不是实际的代码是的。我无法复制他们所犯的错误,而只是关注代码对输出的行为。
using System;
using System.Collections.Generic;
using System.Linq;
                    
    public class Program
    {
        public static void Main(string[] args)
        {
            var orders = new List<Order>();
            orders.Add(new Order(){Year = 2020, Status = "New"});
            orders.Add(new Order(){Year = 2020, Status = "New"});
            orders.Add(new Order(){Year = 2020, Status = "Canceled"});
            orders.Add(new Order(){Year = 2020, Status = "Shipped"});            

            
            var result = orders
                .GroupBy(x=> new {x.Year, x.Status})
                .Select(y => new 
                {   
                    Year = y.Key.Year,
                    Status = y.Key.Status,
                    Count = y.Count()                      
                }).ToList();
            foreach (var item in result)
                {
                    Console.WriteLine(string.Format("{0} {1} {2}",item.Year,item.Status, item.Count));
                }
        }
    }
    public class Order
    {
        public int Year {get;set;}
        public string Status {get;set;}
    }