将IEnumerable与DataModel关联时出现“无法翻译”错误的解决方法
问题原因
你遇到的报错是因为EF Core无法将内存中的IEnumerable集合(packItems)与数据库中的ThirdTable的关联逻辑翻译成SQL语句。由于你提前通过ToListAsync()把packItems拉到了本地内存,后续查询ThirdTable时试图在数据库层面关联这个内存集合,EF无法完成这种跨环境的逻辑翻译。
两种解决方案
方案一:将ThirdTable拉到内存做本地关联(适合数据量小的场景)
如果ThirdTable的数据量不大,可以先把它拉到本地内存,再和已经在内存的packItems做关联操作,全程在内存中完成匹配:
public async Task<IEnumerable<ListOfItems>> ListItemsToday(DateTime today) { var packItems = await GetItems(today); var items = (from ci in _context.ThirdTable.AsEnumerable() // 先将ThirdTable拉到内存 from pi in packItems where pi.colA == ci.colA && pi.colB == ci.colB && pi.colC == ci.colC select new OutputModel { // 填充模型字段 }).ToList(); return items; }
方案二:让整个查询在数据库端执行(推荐,性能更优)
修改GetItems方法返回IQueryable<TableA>(不提前执行查询),这样EF可以把所有关联逻辑翻译成完整的SQL,在数据库端完成计算,避免内存处理大量数据:
首先重构GetItems为查询生成方法:
private IQueryable<TableA> GetItemsQuery(DateTime today) { return from pi in _context.TableA join ph in _context.TableB on pi.SomeCol equals ph.SomeCol where ph.DateCol == today.Date select pi; }
然后修改ListItemsToday,直接用查询表达式做关联:
public async Task<IEnumerable<ListOfItems>> ListItemsToday(DateTime today) { var packItemsQuery = GetItemsQuery(today); var items = await (from ci in _context.ThirdTable join pi in packItemsQuery on new { pi.colA, pi.colB, pi.colC } equals new { ci.colA, ci.colB, ci.colC } select new OutputModel { // 填充模型字段 }).ToListAsync(); return items; }
内容的提问来源于stack exchange,提问作者bmurrell30
相关产品推荐
相关产品推荐

