将 Db Query Result 分成任意多个任务
Divide Db Query Result into as many tasks as I want
我想将 Db 查询结果分成任意多个任务。我能怎么做?比如我想把每300行同时给同一个进程,但是每300行必须是不同的300行。
我不知道你什么意思
I want to give every 300 rows to the same process at the same time
但是,将查询结果划分为任务列表的一种可能解决方案是:
记录总数:
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)
{
...
}
我想将 Db 查询结果分成任意多个任务。我能怎么做?比如我想把每300行同时给同一个进程,但是每300行必须是不同的300行。
我不知道你什么意思
I want to give every 300 rows to the same process at the same time
但是,将查询结果划分为任务列表的一种可能解决方案是:
记录总数:
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)
{
...
}