微信公众号搜"智元新知"关注
微信扫一扫可直接关注哦!

获取按lambdada表达式分组选择的当前记录

如何解决获取按lambdada表达式分组选择的当前记录

我有这张桌子

enter image description here

我想按lifeplusecaseId 字段分组并返回所有分组依据

我已经尝试过了

   var query = db.ApplicantCenterdistance.GroupBy(a => a.LifeplusCaseId)
                    .Select(s => new {
                        Id = s.Key,Mindistance = s.Min(m => m.distance),Duration = s.Min(m => m.Duration),items=s.ToList(),}).Where(x=>x.Mindistance!=" ").ToList();

但是我遇到一个问题,说:

"system.invalidOperationException: 'The LINQ expression '(GroupByShaperExpression:
KeySelector: (a.LifeplusCaseId),ElementSelector:(EntityShaperExpression: "

我不知道如何返回所有记录。

错误是:

system.invalidOperationException:'LINQ表达式'(GroupByShaperExpression: 键选择器:(a.LifeplusCaseId), ElementSelector:(EntityShaperExpression: 实体类型:ApplicantCenterdistance ValueBufferExpression: (ProjectionBindingExpression:空投影成员) IsNullable:错误 ) ) .ToList()'无法翻译。以一种可以翻译的形式重写查询,或者通过插入对AsEnumerable(),AsAsyncEnumerable(),ToList()或ToListAsync()的调用来显式切换到客户端评估。有关更多信息,请参见https://go.microsoft.com/fwlink/?linkid=2101038

解决方法

类似的错误在较早版本的EF中很常见,我已经在EF 6.4.4中测试了此语法,没有发现问题,但是类型结构可能存在其他问题,可能会影响 Linq SQL 表达式评估。

您的错误消息与EF 6.4.4命名不匹配,表明此处有其他问题,但是此错误与EF Core 3.1+匹配。

首先,由于错误是您使用.ToList()所引起的,因此将其从表达式中删除,EF6将支持通过AsEnumerable<>返回分组表达式和投影。以下任何一种都可以在EF6中使用:

.Select(s => new {
    Id = s.Key,MinDistance = s.Min(m => m.Distance),Duration = s.Min(m => m.Duration),items = s
})

或通过.AsEnumerable<ApplicantCenterDistance>()

投射
.Select(s => new {
    Id = s.Key,items = s.AsEnumerable<ApplicantCenterDistance>()
})

如果您仍然遇到问题,也可以将过滤条件移至投影之前,这样可以在客户端评估投影(以及.ToList()之前的投影),这是异常消息和相关的MS Docs article提示:

var query = db.ApplicantCenterDistance
                .GroupBy(a => a.LifeplusCaseId)
                .Where(x => x.Where(x => x.Min(m => m.Distance) != " ")
                .Select(s => new {
                    Id = s.Key,items=s.ToList(),}).ToList();

更新:EF Core

如果要在EF Core 3.1+中执行此操作,则一种选择是将整个记录集拉入客户端的内存中,并将其分组。如果无论如何结果的数量总是很大,那么这将不会有太大的影响,因为您已经将所有项目都保留在每个组中了

var dataList = db.ApplicantCenterDistance.ToList();
var data = dataList
                .GroupBy(a => a.LifeplusCaseId)
                .Select(s => new {
                    Id = s.Key,}).Where(x=>x.MinDistance!=" ").ToList();

更新:字符串字段上的MIN

由于Distance是一个字符串,如果您确实想要最小值,MIN可能无法评估正确的数字比较,为此您需要将其转换为数字类型。

注意::您可以在以上任何查询中使用此语法,但是,如果要在数据库中执行评估,则需要在最后一次转换为double在客户端示例中,您可以使用任何希望转换值的C#代码。

MinDistance = s.Where(m => m != " ").Min(m => (double)m.Distance),

在这里,我们首先要过滤掉不能转换为数字的值,您可能需要根据数据集是否包含空值或零长度字符串来进行调整。 See this post了解更多详情。

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。