如何在EF Core 3.1中执行GroupBy

时间:2020-02-27 12:09:33

标签: c# asp.net ef-core-2.2 ef-core-3.0 ef-core-3.1

我们已将应用程序从2.1升级到Core 3.1。以下查询不再起作用。 重写它的最佳方法是什么?

    public async Task<Dictionary<int, CoStatusUpdate>> GetDailyStatusUpdates(int organisationTypeId)
    {
        var dailyUpdates = await _context.CoStatusUpdates
            .Include(x => x.CoStatus)
            .Include(x => x.Company).ThenInclude(x => x.Organisation)
            .GroupBy(p => p.CompanyId)
                .Select(x => new CoStatusUpdate
                {
                    CompanyId = x.Key,
                    Company = new Company() //building new object for the only fields we need otherwise there's way more returned than needed
                    {
                        Organisation = new Organisation()
                        {
                            Name = x.FirstOrDefault(y => y.SubmittedDateTime == x.Max(z => z.SubmittedDateTime)).Company.Organisation.Name,
                            IsDeleted = x.FirstOrDefault(y => y.SubmittedDateTime == x.Max(z => z.SubmittedDateTime)).Company.Organisation.IsDeleted,
                            OrganisationTypeId = x.FirstOrDefault(y => y.SubmittedDateTime == x.Max(z => z.SubmittedDateTime)).Company.Organisation.OrganisationTypeId,
                        }
                    },
                    CoStatusUpdateId = x.FirstOrDefault(y => y.SubmittedDateTime == x.Max(z => z.SubmittedDateTime)).CoStatusUpdateId,
                    CoStatusId = x.FirstOrDefault(y => y.SubmittedDateTime == x.Max(z => z.SubmittedDateTime)).CoStatusId,
                    CoStatus = x.FirstOrDefault(y => y.SubmittedDateTime == x.Max(z => z.SubmittedDateTime)).CoStatus,
                    SubmittedDateTime = x.Max(z => z.SubmittedDateTime)
                }).Where(x => !x.Company.Organisation.IsDeleted
                     && x.Company.Organisation.OrganisationTypeId == organisationTypeId))
            .ToDictionaryAsync(x => x.CompanyId);

        return dailyUpdates;
    }

错误是:

{“ LINQ表达式'(GroupByShaperExpression:\ r \ nKeySelector:(f.CompanyId),\ r \ nElementSelector:(EntityShaperExpression:\ r \ n EntityType:CoStatusUpdate \ r \ n ValueBufferExpression:\ r \ n(ProjectionBindingExpression :EmptyProjectionMember)\ r \ n IsNullable:False \ r \ n)\ r \ n)\ r \ n .FirstOrDefault(y => y.SubmittedDateTime ==(GroupByShaperExpression:\ r \ n KeySelector:(f.CompanyId), \ r \ n ElementSelector:(EntityShaperExpression:\ r \ n EntityType:CoStatusUpdate \ r \ n ValueBufferExpression:\ r \ n(ProjectionBindingExpression:EmptyProjectionMember)\ r \ n IsNullable:False \ r \ n)\ r \ n)\ r \ n .Max(z => z.SubmittedDateTime))'无法翻译。要么以可以翻译的形式重写查询,要么通过插入对AsEnumerable(),AsAsyncEnumerable()的调用来显式切换到客户端评估,ToList()或ToListAsync()。有关更多信息,请参见https://go.microsoft.com/fwlink/?linkid=2101038。“}

编辑:

我的方案的解决方案

虽然我接受了给出的第一个答案(它提供了与该查询在Core 2.1中所做的等同的工作),但我现在找到了一种实际执行分组服务器端方法,该方法性能更高。

        var coUpdates = await _context.Companys
            .Where(p=>!p.Organisation.IsDeleted)  
            .Select(p => p.CompanyId)
          //.Distinct() //if you wouldn't already be getting a unique list of id's
            .Select(id => _context.coStatusUpdates
                .Include(u=>u.coStatus)
                .Include(u=>u.Company).ThenInclude(x=>x.Organisation)
                .OrderByDescending(p => p.SubmittedDateTime)  
                .FirstOrDefault(p => p.CompanyId == id))  
            .ToListAsync();

        var coUpdatesDictionary = coUpdates
            .Where(x => x != null)
            .ToDictionary(x=>x.CompanyId);

        return coUpdatesDictionary;

1 个答案:

答案 0 :(得分:1)

您需要将其分为两个不同的查询:

this.obj.currentPage