GroupBy Expression无法翻译

时间:2020-01-07 17:57:40

标签: entity-framework entity-framework-6 ef-core-3.0 .net-core-3.1

//Model
public class Application
{
    [Key]
    public int ApplicationId { get; set; }
    public DateTime CreatedAt { get; set; }
    public DateTime ConfirmedDate { get; set; }
    public DateTime IssuedDate { get; set; }
    public int? AddedByUserId { get; set; }
    public virtual User AddedByUser { get; set; }
    public int? UpdatedByUserId { get; set; }
    public virtual User UpdatedByuser { get; set; }
    public string FirstName { get; set; }
    public string MiddleName { get; set; }
    public string LastName { get; set; }
    public string TRN { get; set; }
    public string EmailAddress { get; set; }
    public string Address { get; set; }
    public int ParishId { get; set; }
    public Parish Parish { get; set; }
    public int? BranchIssuedId { get; set; }
    public BranchLocation BranchIssued { get; set; }
    public int? BranchReceivedId { get; set; }
    public BranchLocation BranchReceived {get; set; }
}

public async Task<List<Application>> GetApplicationsByNameAsync(string name)
{
    if (string.IsNullOrEmpty(name))
        return null;
    return await _context.Application
        .AsNoTracking()
        .Include(app => app.BranchIssued)
        .Include(app => app.BranchReceived)
        .Include(app => app.Parish)
        .Where(app => app.LastName.ToLower().Contains(name.ToLower()) || app.FirstName.ToLower()
        .Contains(name.ToLower()))
        .GroupBy(app => new { app.TRN, app })
        .Select(x => x.Key.app)
        .ToListAsync()
        .ConfigureAwait(false);
}

以上GroupBy表达式无法在VS Studio中编译。我的目标是运行一个查询,该查询按名称过滤结果,其中包含用户给定的字符串,然后按类似的TRN数字对结果进行分组,以返回这些应用程序的列表以返回视图。我想我真的很接近,但似乎无法弄清楚查询的最后一点。任何指导表示赞赏。

出现错误

InvalidOperationException: The LINQ expression 'DbSet<Application>
.Where(a => a.LastName.ToLower().Contains(__ToLower_0) || a.FirstName.ToLower().Contains(__ToLower_0))
.GroupBy(
source: a => new {
TRN = a.TRN,
app = a
},
keySelector: a => a)' 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 either AsEnumerable(), AsAsyncEnumerable(), ToList(), or ToListAsync()

更新 似乎肯定是由于自从最近的更新以来.net core 3.x和EF core的交互方式发生了变化。我必须使用AsEnumerable()而不是ToListAsync()将其更改为客户评估。 Steve py给出的其余查询都使用此方法。即使在阅读了文档后,我仍然不知道groupby在LINQ中是如何工作的,所以这对我有很大帮助。但是,将查询带到客户端评估可能会出现性能问题。

2 个答案:

答案 0 :(得分:1)

基于此:

我想按重复的数字TRN分组,例如12345,在应用程序表中可能有许多具有相同序列的记录,而我只希望每组TRN序列中的最新行。 >

我相信这应该可以满足您的需求:

return await _context.Application
    .AsNoTracking()
    .Include(app => app.BranchIssued)
    .Include(app => app.BranchReceived)
    .Include(app => app.Parish)
    .Where(app => app.LastName.ToLower().Contains(name.ToLower()) || app.FirstName.ToLower()
    .Contains(name.ToLower()))
    .GroupBy(app => app.TRN)
    .Select(x => x.OrderByDescending(y => y.CreatedAt).First())
    .ToListAsync()
    .ConfigureAwait(false);

GroupBy表达式应表示您要分组的内容。就您而言,TRN。从那里开始选择时,x代表每个“组”,其中包含属于每个TRN的应用程序的可枚举集。因此,我们按降序的CreatedAt日期排序,以使用First选择最新的日期。

给个机会。如果不是您想要的,请考虑为您的问题添加一个示例集,并提供所需的输出以及此处产生的输出/错误。

答案 1 :(得分:0)

我遇到了类似的问题,我同时发现它既有趣又愚蠢。似乎EF团队禁止在GROUP BY之前执行WHERE,因此它不起作用。我不明白为什么你不能做到这一点,但是这似乎是迫使我执行过程而不是很好地构建代码的方式。

LMK(如果找到方法)。

注意:只有在您第一次分组然后在何处(完整表格中分组元素的位置=>对我来说没有意义)时,它们才会进行分组。