【发布时间】:2020-03-13 22:32:52
【问题描述】:
在 EF Core 2.2 中,我有:
var data = await _ArticleTranslationRepository.DbSet
.Include(arttrans => arttrans.Article)
.ThenInclude(art => art.Category)
.Where(trans => trans.Article != null && trans.Article.Category != null && trans.Article.Category.Id == categoryId.Value)
.GroupBy(trans => trans.ArticleId)
.Select(g => new { ArticleId = g.Key, TransInPreferredLang = g.OrderByDescending(trans => trans.LanguageId == lang).ThenByDescending(trans => trans.LanguageId == defaultSiteLanguage).ThenBy(trans => trans.LanguageId).FirstOrDefault() })
.Select(at => at.TransInPreferredLang)
.OrderBy(at => at.Article.SortIndex)
.ToListAsync();
现在使用 EF Core 3.0 我必须编写:
var data = _ArticleTranslationRepository.DbSet
.Include(arttrans => arttrans.Article)
.ThenInclude(art => art.Category)
.Where(trans => trans.Article != null && trans.Article.Category != null && trans.Article.Category.Id == categoryId.Value)
.AsEnumerable() // client side groupby is not supported (.net core 3.0 (18 nov. 2019)
.GroupBy(trans => trans.ArticleId)
.Select(g => new { ArticleId = g.Key, TransInPreferredLang = g.OrderByDescending(trans => trans.LanguageId == lang).ThenByDescending(trans => trans.LanguageId == defaultSiteLanguage).ThenBy(trans => trans.LanguageId).FirstOrDefault() })
.Select(at => at.TransInPreferredLang)
.OrderBy(at => at.Article.SortIndex)
.ToList();
我的 asp.net 核心 mvc actionmethod 是异步的 (public virtual async Task<ICollection<…>>…)
因为我使用 .AsEnumerable 来强制客户端评估,所以我还必须将 .ToListAsync() 更改为 .ToList() 并删除 await 运算符。
查询正在运行,但会产生警告:
This async method lacs 'await' operators and will run synchronously. Consider using the 'await operator ….
如何重写此 EF Core 3.0 查询以使其使用异步/等待。我不知道如何在 single 查询/linq 表达式中包含 AsAsyncEnumerable()。
(我知道我可以将其拆分为“服务器”部分和“客户端”部分,但我希望在单个 async linq 表达式中看到它在 EF Core 2.2 之前。)
【问题讨论】:
-
为什么需要强制客户端评估?而不是
AsEnumerable使用ToListAsync并将其结果存储在一个变量中,然后对其进行其余的查询。 -
因为使用 .GroupBy 时“不支持客户端 groupby”
-
@Fildor:我已经重写了它,它工作我正在使用 Asenumerable()。但它现在不再使用异步等待了。我确实可以将它拆分为服务器端部分和客户端部分,但我想知道是否可以使用例如 AsAsyncEnumerable 在单个 linq“表达式”中异步编写它。
-
啊,我没抓住重点。是的,我同意,如果不将其撕成两半,我不知道怎么做。
-
你可以做
(await /* ... */.ToListAsync()).GroupBy( /* ... */- 即将数据库执行的一半包裹在括号中,等待它,然后继续等待结果的链 - 在单个语句中完成。
标签: c# entity-framework async-await entity-framework-core ef-core-3.0