gpt4 book ai didi

c# - Entity Framework 不翻译 Linq 表达式

转载 作者:行者123 更新时间:2023-12-05 02:26:52 26 4
gpt4 key购买 nike

我有以下数据模型,我需要根据这些条件对 ResponseItem 列表进行分组:

  • 首先: 按 ResponseItem.Group 分组
  • 第二个:按 ResponseItem.SubGroup 分组,但只考虑最近的一个,这意味着考虑 ResponseItem.CreationDate

代码:

    public class ResponseItem
{
public string Group { get; set; }
public string SubGroup { get; set; }
public double Value { get; set; }
public DateTime CreationDate { get; set; }
}

public class GroupedResponseItem
{
public string Group { get; set; }
public List<ResponseItem> Items { get; set; }
}

方法是:

public List<GroupedResponseItem> GetGroupedData( IQueryable<ResponseItem> responseItems )
{
return responseItems
.OrderByDescending(i => i.CreationDate)
.GroupBy(i => i.Group)
.Select(grp => new GroupedResponseItem()
{
Group = grp.Key,
Items = grp
.GroupBy(i => new { i.SubGroup })
.Select(grp => grp.First())
.Select(i => new ResponseItem()
{
SubGroup = i.SubGroup,
CreationDate = i.CreationDate,
Value = i.Value
}).ToList()
})
.ToList();
}

但是我得到一个错误:

'The LINQ expression 'ProjectionBindingExpression: 0' could not be translated. Either rewrite the query in a form that can be translated, or switch to client evaluation explicitly by inserting a call to 'AsEnumerable', 'AsAsyncEnumerable', 'ToList', or 'ToListAsync'

正如我在标题中提到的,我在 .NET 6 上使用 Entity Framework。

另一方面,如果我不考虑第二个分组依据,查询工作正常:

public List<GroupedResponseItem> GetGroupedData(IQueryable<ResponseItem> responseItems)
{
return responseItems
.OrderByDescending(i => i.CreationDate)
.GroupBy(i => i.Group)
.Select(grp => new GroupedResponseItem()
{
Group = grp.Key,
Items = grp
.Select(i => new ResponseItem()
{
SubGroup = i.SubGroup,
CreationDate = i.CreationDate,
Value = i.Value
})
.ToList()
})
.ToList();
}

最佳答案

罪魁祸首似乎是这里的二次投影(Select)

.GroupBy(i => new { i.SubGroup })
.Select(grp => grp.First()) // <-- (1)
.Select(i => new ResponseItem() // <-- (2)
{
SubGroup = i.SubGroup,
CreationDate = i.CreationDate,
Value = i.Value
})
.ToList()

虽然 EF Core 6.0 改进了 GroupBy 的翻译,在分组结果集上添加了额外的运算符(键/聚合除外,它们具有自然的 SQL 支持),但仍然存在一些限制/缺陷阻止某些翻译结构体。特别是多重投影。

很快,GroupBy 之后的Select 必须是最终的 LINQ 运算符。这有点令人难过,因为中间投影通常有助于翻译,并且通常用于解决 EF Core 限制。但在这种情况下不是。

对于这个特定的查询,投影看起来是多余的,因为组元素的类型与投影类型相同,所以它可以简单地被删除

.GroupBy(i => new { i.SubGroup })
.Select(grp => grp.First()) // <-- final projection
.ToList()

所以这是解决方案/解决方法之一。如果你真的需要一个投影,因为你正在选择部分列,或者投影到不同的类型,那么将它移动到 GroupBy 之后的 Select 中:


.GroupBy(i => new { i.SubGroup })
.Select(grp => grp
.Select(i => new ResponseItem()
{
SubGroup = i.SubGroup,
CreationDate = i.CreationDate,
Value = i.Value
})
.First()
) // <-- final projection
.ToList()

关于c# - Entity Framework 不翻译 Linq 表达式,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/73587447/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com