使用 .NET Core 进行分组的 Linq 查询

Posted

技术标签:

【中文标题】使用 .NET Core 进行分组的 Linq 查询【英文标题】:Linq query with group by with .NET Core 【发布时间】:2021-08-18 07:34:44 【问题描述】:

我正在尝试做一个简单的查询。我想要一个带有字符串和 Guid 的列表以及带有小数点和字符串的子列表。我以这种方式进行查询,但是在转换为实体框架时它一直出错我做错了什么?

提前致谢

var a = (        from c in DbContext.CC
                 join icc in DbContext.ICC c.Id equals icc.CCId
                 join i in DbContext.I on icc.IId equals i.Id
                 join p in DbContext.P on i.PId equals p.Id
                 select new
                 
                     GuidId = p.Id,
                     StringN = p.StringN,
                     CCString = c.CCString ,
                     DecimalValue = icc.DecimalValue 
                 ).GroupBy(x => new  x.GuidId , x.StringN ).
                 Select(x => new Model
                 
                     GuidId = x.Key.GuidId ,
                     StringN = x.Key.StringN , 
                     Values= x.Select(y => new OtherModel
                     
                         DecimalValue = y.DecimalValue ,
                         CCString = y.CCString 
                     )
                 
          ).OrderBy(x => x.StringN );

错误:

LINQ 表达式 '(GroupByShaperExpression: 键选择器:新 GuidId = (p.Id), StringN = (p.Name) , 元素选择器:新 GuidId = (ProjectionBindingExpression: GuidId), StringN = (ProjectionBindingExpression: StringN), CCString = (ProjectionBindingExpression: CCString), DecimalValue = (ProjectionBindingExpression: DecimalValue) ) .Select(y => new OtherModel DecimalValue = y.DecimalValue , CCString = y.CCString )' 无法翻译。以可翻译的形式重写查询,或通过插入对 AsEnumerable()、AsAsyncEnumerable()、ToList() 或 ToListAsync() 的调用显式切换到客户端评估。请参阅https://go.microsoft.com/fwlink/?linkid=2101038 了解更多信息。

【问题讨论】:

x.Key 没有CCString 成员(因此第二次选择失败)。 Model 没有 StringN 成员,因此 OrderBy 失败。你说它在翻译成 EF 时会失败,但它根本不应该编译。你也没有说错误是什么 抱歉,快速复制.. 我已经编辑了我的代码,它应该是 StringN 而不是 CCString。另外,用错误更新了帖子。谢谢 您的问题仍然存在语法错误。请确认您的minimal reproducible example 是正确的 我遇到的错误是在第三个选择中,我需要执行以获取值。我可以用其他方式吗? 正如@RodrigoRodrigues 已经说过的,请提供此查询中涉及的实体类以及每个表中的两个或三个值以及查询的期望结果。在这种情况下,我们可以在本地机器上测试和调试您的问题。在访问智能感知、调试器和源数据时,您无法发现错误。因此,不要指望任何人在不了解底层数据结构且无法测试或调试它的情况下仅通过查看您的查询就能发现错误。 【参考方案1】:

这是 SQL 限制。不能选择分组项,只能选择 Key 和聚合结果。

AsEnumerable 添加到您的 LINQ 查询以在客户端进行分组:

var a = (       
    from c in DbContext.CC
    join icc in DbContext.ICC c.Id equals icc.CCId
    join i in DbContext.I on icc.IId equals i.Id
    join p in DbContext.P on i.PId equals p.Id
    select new
    
        GuidId = p.Id,
        StringN = p.StringN,
        CCString = c.CCString,
        DecimalValue = icc.DecimalValue 
    )
    .AsEnumerable()
    .GroupBy(x => new  x.GuidId , x.StringN )
    .Select(x => new Model
    
        GuidId = x.Key.GuidId,
        StringN = x.Key.StringN, 
        Values = x.Select(y => new OtherModel
        
            DecimalValue = y.DecimalValue,
            CCString = y.CCString 
        )
    )
    .OrderBy(x => x.StringN);

【讨论】:

就是这样!谢谢@Svyatoslav Danyliv

以上是关于使用 .NET Core 进行分组的 Linq 查询的主要内容,如果未能解决你的问题,请参考以下文章

ASP NET Core 中 HttpGet 中的分组依据

如何在 Dynamic Linq Core 中无任何分组

对DataTable进行分组

Linq,EF Core - 按一个字段分组并使用其他字段从其他表中获取数据列表

.NET(C#) System.Linq中实现多列group by(分组)的示例代码

Linq 查询在 ASP.NET-Core 3.0 及更高版本中对数字等字符串进行排序