首页 > 解决方案 > 从 Sqlite 获取项目并删除重复项目时的 InvalidOperation

问题描述

我想从sqlite数据库中获取项目(数据库中大约有6000个项目)有些项目是重复的因此,我想在获取项目时删除这个重复的信息

我使用了以下代码

public async static Task<List<myModel>> GetAllItems()
        {
            using var db = new dbContext();
            var query =
                from item in db.myTable.GroupBy(x => x.Id).Select(x => x.First())
                select new myModel
                {
                    Id = item.Id,
                    Name = item.Name,
                    ...
                };
            return await query.ToListAsync();
        }

但我收到以下错误

System.InvalidOperationException: 'The LINQ expression 'GroupByShaperExpression:
KeySelector: m.Id, 
ElementSelector:EntityShaperExpression: 
    EntityType: myTable
    ValueBufferExpression: 
        ProjectionBindingExpression: EmptyProjectionMember
    IsNullable: False

    .First()' 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'. See https://go.microsoft.com/fwlink/?linkid=2101038 for more information.'

标签: c#entity-framework-core

解决方案


更新(EF Core 6.0):

EF Core 6.0 确实为结果集添加了对一些额外运算符的支持GroupBy,包括有问题的运算符,因此现在原始 LINQ 查询应该可以正常工作。

原来的:

由于目前(希望 v6.0 会添加一些)EF Core 不支持GroupBy键/聚合投影以外的结果运算符,它不能用于实现每个组函数的前 N ​​个项目,这就是您基本上正在尝试做的事情(对于N == 1)。

因此,作为一种解决方法(没有第 3 方扩展),您必须通过 (1) 使用子查询来选择唯一键,然后 (2) 将其用作相关限制子查询的过滤器来手动执行此操作。例如类似的东西

var query = db.myTable.Select(x => new { x.Id }).Distinct() // (1)
    .SelectMany(key => db.myTable.Where(x => x.Id == key.Id).Take(1)) // (2)
    // The rest is the same as the original
    .Select(item => new myModel
    {
        Id = item.Id,
        Name = item.Name,
        ...
    });

推荐阅读