我想将Db查询结果划分为我想要的尽可能多的任务。我该怎么办?例如,我想在同一时间将每300行分配给同一个进程,但每300行必须是不同的300行。
我不知道你是什么意思
然而,将查询结果划分为任务列表的一种可能的解决方案是:我想在同一时间给同一个进程每300行
记录总数:
var count = await context.Entities.CountAsync();
计算您需要的总数据库调用:
const int take = 300; var dbCallsCount = Math.Ceiling((double)count / take);
创建一个获取数据的方法(注意不能通过同一个
DbContext
对象运行并行查询):public async Task<List<Entity>> FetchDataAsync(int page, int take) { using(var context = new DbContext("ConnectionString")) { var result = await context.Entities .AsNoTracking() .Skip((page - 1) * take) .Take(take) .ToListAsync(); return result; } }
创建一个获取数据的任务列表:
var taskList = new List<Task<List<Entity>>>(); for(var i = 0; i < dbCallsCount; i++) taskList.Add(FetchDataAsync(i, take)); var result = await Task.WhenAll(taskList);
它可以是一个通用的方法来获取数据的任务列表:
public async Task<List<Task<List<TEntity>>>> DivideDbQueryIntoTasks<TEntity>(int take) where TEntity : class
{
int count;
using(var context = new DbContext("ConnectionString"))
{
count = await context.DbSet<TEntity>.CountAsync();
}
var dbCallsCount = Math.Ceiling((double)count / take);
// Local function
async Task<List<TEntity>> FetchDataAsync<TEntity>(int page, int take)
{
using(var context = new DbContext("ConnectionString"))
{
var result = await context.DbSet<TEntity>
.AsNoTracking()
.Skip((page - 1) * take)
.Take(take)
.ToListAsync();
return result;
}
}
var taskList = new List<Task<List<TEntity>>>();
for(var i = 0; i < dbCallsCount; i++)
taskList.Add(FetchDataAsync<TEntity>(i, take));
return taskList;
}
然后这样调用:
var tasks = await DivideDbQueryIntoTasks<MyEntity>(300);
foreach (Task<List<IdentityUser>> task in tasks)
{
...
}