Jon*_*ood 0 c# entity-framework async-await entity-framework-core .net-core
以下代码有效。
employees.AddRange(from e in DbContext.Employees
select new EmployeeSummaryModel
{
Name = e.Name,
Email = e.Email
});
Run Code Online (Sandbox Code Playgroud)
但是我将如何重写此查询以使用await?请注意,我不想使用,ToListAsync()因为这会不必要地创建第二个列表?
AddRange本质上是同步的。有多种选项可以使此异步,具体取决于结果的使用方式
只是一个列表
一种选择是使用返回的列表ToListAsync而不是提前创建列表:
var employees= await query.ToListAsync();
Run Code Online (Sandbox Code Playgroud)
如果第一个是空的,就没有理由有两个列表。
使用异步流
另一种选择是使用AsAsyncEnumerable异步执行查询并取回 IAsyncEnumerable。这必须迭代以将数据逐项复制到现有列表中:
await foreach(var emp in query.AsAsyncEnumerable())
{
employees.Add(emp);
}
Run Code Online (Sandbox Code Playgroud)
如果原始列表已经包含数据,这很有用。双方Add并AddRange会引起列表的内部缓冲区虽然重新分配的。
使用有容量的空列表
如果您对结果数量有一个粗略的想法,您可以创建一个具有特定容量的列表,并至少避免一些重新分配:
var employees=new List<Employee>(100);
await foreach(var emp in query.AsAsyncEnumerable())
{
employees.Add(emp);
}
Run Code Online (Sandbox Code Playgroud)
异步管道
如果你有很多数据,你可能不应该甚至暂时将它们存储在列表中。您可以创建一个方法管道,IAsyncEnumerable在数据到达时接受、返回和处理数据,只在最后缓存它们。您可以为此使用System.Linq.Async的运算符
query.AsAsyncEnumerable()
.Select(emp=>EnrichFromApiAsync(emp,someUrl))
...
.ToListAsync();
Run Code Online (Sandbox Code Playgroud)
或将其转换为Observablewith ToObservable(),在到达管道末端时处理最终转换的数据
| 归档时间: |
|
| 查看次数: |
413 次 |
| 最近记录: |