并行运行多个实体框架数据库查询

本文关键字:框架 数据库 查询 实体 运行 并行 | 更新日期: 2023-09-27 17:57:23

我正在尝试并行运行 3 个数据库查询,但我不确定我是否正确。

我做了 3 个函数,每个函数都对数据库进行查询。

private static async Task<string> getAccountCodeAsync(string deviceId)
{
    long deviceIdLong = long.Parse(deviceId);
    using (var db = new NetworksEntities())
    {
        return db.Devices.Where(x => x.DeviceId == deviceIdLong)
            .Select(x => x.AccountCode)
            .FirstOrDefault();
    }
}
private static async Task<string> getDeviceTypeAsync(string deviceId)
{
    long deviceIdLong = long.Parse(deviceId);
    using (var db = new NetworksEntities())
    {
        return db.Devices.Where(x => x.DeviceId == deviceIdLong)
            .Select(x => x.DeviceType)
            .FirstOrDefault()
            .DeviceType;
    }
}
private static async Task<string> getUserNameAsync(string userId)
{
    int userIdInt;
    Int32.TryParse(userId, out userIdInt);
    using (var db = new NetworksEntities())
    {
        return db.Users.Where(x => x.UserId == userIdInt)
            .Select(x => x.Email)
            .FirstOrDefault();
    }
}   

然后,我在代码中运行三个任务:

var TaskAccountCode = await getAccountCodeAsync(deviceId);
var TaskDeviceType = await getDeviceTypeAsync(deviceId);
var TaskUsername = await getUserNameAsync(userId);
await Task.WhenAll();   
// use the results from my 3 tasks to make a new insert into the db.

我正在做的事情实际上是并行运行我的 3 db 查询吗?

编辑:

private static async Task<string> getAccountCodeAsync(string deviceId)
{
    long deviceIdLong = long.Parse(deviceId);
    using (var db = new NetworksEntities())
    {               
        return db.Devices.Where(x => x.DeviceId == deviceIdLong)
            .Select(x => x.AccountCode)
            .FirstOrDefaultAsync();
    }
}

并行运行多个实体框架数据库查询

您必须更改代码的最后一部分以使其并行运行:

var taskAccountCode = getAccountCodeAsync(deviceId);
var taskDeviceType = getDeviceTypeAsync(deviceId);
var taskUsername = getUserNameAsync(userId);
await Task.WhenAll(taskAccountCode, taskDeviceType, taskUsername);
var accountCode = taskAccountCode.Result;
var deviceType = taskDeviceType.Result;
var username  = taskUsername.Result;

请注意,只有一个await。在原始代码中,您一个接一个地await每个任务,使它们按顺序运行而不是并行运行。

此外,方法getAccountCodeAsync等并不是真正的异步方法(您应该收到有关此的编译器警告)。但是,实体框架 6 支持异步操作,若要使用该操作,应将FirstOrDefault替换为 FirstOrDefaultAsync 。对于每个并行操作,您都必须使用单独的上下文,而这正是您正在执行的操作。

不,如果您使用 await foreach 方法这样调用它们,它们会一个接一个地运行,它将运行第一个方法,然后运行第二个方法......等。最后一部分await Task.WhenAll(),您没有提供等待完成的任务。

要并行运行它们,您必须这样做:

var TaskAccountCode = getAccountCodeAsync(deviceId);
var TaskDeviceType = getDeviceTypeAsync(deviceId);
var TaskUsername = getUserNameAsync(userId);
await Task.WhenAll(TaskAccountCode, TaskDeviceType,TaskUsername);