kab*_*178 6 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);
}
Run Code Online (Sandbox Code Playgroud)
上述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()
Run Code Online (Sandbox Code Playgroud)
更新
看来这肯定是由于最近更新以来 .net core 3.x 和 EF core 一起运行的方式发生了变化。我不得不使用AsEnumerable()而不是将其更改为客户评估ToListAsync()。Steve py 给出的其余查询适用于此方法。即使在阅读了文档之后,我也不知道 groupby 在 LINQ 中是如何工作的,所以这对我帮助很大。然而,将查询传递给客户端评估可能会产生性能问题。
EF core 中的 GroupBy 支持就是一个笑话。
这在 EF6 的服务器上完美运行
var nonUniqueGroups2 = db.Transactions.GroupBy(e => new { e.AccountId, e.OpeningDate })
.Where(grp => grp.Count() > 1).ToList();
Run Code Online (Sandbox Code Playgroud)
在 EF core 中,它会导致异常“无法转换给定的 'GroupBy' 模式。在 'GroupBy' 之前调用 'AsEnumerable' 以在客户端对其进行评估。” 该消息具有误导性,请勿致电,AsEnumerable因为这应该在服务器上处理。
我在这里找到了解决方法。额外的Select会有帮助。
var nonUniqueGroups = db.Transactions.GroupBy(e => new { e.AccountId, e.OpeningDate })
.Select(x => new { x.Key, Count = x.Count() })
.Where(x => x.Count > 1)
.ToList();
Run Code Online (Sandbox Code Playgroud)
该解决方法的缺点是结果集不包含组中的项目。
存在 EF Core问题。请对其进行投票,以便他们真正解决此问题。
基于此:
我想按 TRN 进行分组,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);
Run Code Online (Sandbox Code Playgroud)
该GroupBy表达式应该代表您想要分组的内容。就您而言,TRN。当我们进行选择时,x代表每个“组”,其中包含属于每个 TRN 的可枚举应用程序集。因此,我们按 CreatedAt 日期降序排列它们,以使用 来选择最新的First。
试一试。如果这不完全是您想要的,请考虑向您的问题添加一个示例集,以及所需的输出与此处产生的输出/错误。
| 归档时间: |
|
| 查看次数: |
10427 次 |
| 最近记录: |