c# - Entity Framework 6 异步方法与同步方法的性能

标签 c# entity-framework asynchronous

我修改了一个 Github 项目来测试更多与 Entity Framework 相关的查询方式。

Link

模型:

[Table("Player")]
public partial class Player
{
    public int Id { get; set; }

    [Required]
    [StringLength(200)]
    public string FirstName { get; set; }

    [Required]
    [StringLength(200)]
    public string LastName { get; set; }

    public DateTime DateOfBirth { get; set; }

    public int TeamId { get; set; }

    public virtual Team Team { get; set; }
}

[Table("Team")]
public partial class Team
{
    public Team()
    {
        Players = new HashSet<Player>();
    }

    public int Id { get; set; }

    [Required]
    [StringLength(200)]
    public string Name { get; set; }

    public DateTime FoundingDate { get; set; }

    public int SportId { get; set; }

    public virtual ICollection<Player> Players { get; set; }

    public virtual Sport Sport { get; set; }
}

[Table("Sport")]
public partial class Sport
{
    public Sport()
    {
        Teams = new HashSet<Team>();
    }

    public int Id { get; set; }

    [StringLength(100)]
    public string Name { get; set; }

    public virtual ICollection<Team> Teams { get; set; }
}

我正在测试的是这些东西:

EF“同步”- FirstOrDefault() 和 ToList()

context.Players.FirstOrDefault(x => x.Id == id);

context.Players.AsNoTracking().Where(x => x.TeamId == teamId).ToList();

context.Teams.AsNoTracking().Include(x => x.Players).Where(x => x.SportId == sportId).ToList();

EF“异步”- FirstOrDefaultAsync() 和 ToListAsync()

await context.Players.FirstOrDefaultAsync(x => x.Id == id);

await context.Players.AsNoTracking().Where(x => x.TeamId == teamId).ToListAsync();

await context.Teams.AsNoTracking().Include(x => x.Players).Where(x => x.SportId == sportId).ToListAsync();

EF 与 Select 同步到 DTO 对象

context.Players.Select(p => new PlayerDTO()
                {
                    Id = p.Id,
                    FirstName = p.FirstName,
                    DateOfBirth = p.DateOfBirth,
                    LastName = p.LastName,
                    TeamId = p.TeamId

                }).FirstOrDefault(x => x.Id == id);

context.Players.Where(x => x.TeamId == teamId).Select(p => new PlayerDTO()
                {
                    Id = p.Id,
                    FirstName = p.FirstName,
                    DateOfBirth = p.DateOfBirth,
                    LastName = p.LastName,
                    TeamId = p.TeamId
                }).ToList();

context.Teams.Where(x => x.SportId == sportId).Select(t => new TeamDTO()
                    {
                        Id = t.Id,
                        FoundingDate = t.FoundingDate,
                        Name = t.Name,
                        SportId = t.SportId,
                        Players = t.Players.Select(p => new PlayerDTO()
                        {
                            Id = p.Id,
                            FirstName = p.FirstName,
                            DateOfBirth = p.DateOfBirth,
                            LastName = p.LastName,
                            TeamId = p.TeamId
                        }).ToList()
                    }).ToList();

EF“异步”选择 DTO 对象

await context.Players.Select(p => new PlayerDTO()
                {
                    Id = p.Id,
                    FirstName = p.FirstName,
                    DateOfBirth = p.DateOfBirth,
                    LastName = p.LastName,
                    TeamId = p.TeamId

                }).FirstOrDefaultAsync(x => x.Id == id);

 await context.Players.Where(x => x.TeamId == teamId).Select(p => new PlayerDTO()
                {
                    Id = p.Id,
                    FirstName = p.FirstName,
                    DateOfBirth = p.DateOfBirth,
                    LastName = p.LastName,
                    TeamId = p.TeamId
                }).ToListAsync();

await context.Teams.Where(x => x.SportId == sportId).Select(t => new TeamDTO()
                {
                    Id = t.Id,
                    FoundingDate = t.FoundingDate,
                    Name = t.Name,
                    SportId = t.SportId,
                    Players = t.Players.Select(p => new PlayerDTO()
                    {
                        Id = p.Id,
                        FirstName = p.FirstName,
                        DateOfBirth = p.DateOfBirth,
                        LastName = p.LastName,
                        TeamId = p.TeamId
                    }).ToList()
                }).ToListAsync();

我认为我的结果很麻烦。主要是因为 MS 正在大量推广 EF 的异步部分。

我的结果:(以毫秒为单位)

运动数量:8,球队数量:30,球员数量:100

EntityFrameworkAsyncDTO Results
Run #   Player by ID            Players per Team                Teams per Sport
0               1,46                    3,47                    35,88
1               1,04                    3                       33
2               1,02                    3,3                     33,75
3               1,03                    3                       31,75
4               1,1                     3,27                    31,38
EntityFrameworkAsync Results
Run #   Player by ID            Players per Team                Teams per Sport
0               1,17                    3,53                    57
1               1,01                    3                       48,62
2               0,99                    3,03                    47,88
3               1,02                    3,07                    51
4               1                       3,03                    48,88
EntityFrameworkDTO Results
Run #   Player by ID            Players per Team                Teams per Sport
0               0,02                    3                       13,25
1               0,01                    2,8                     13,12
2               0,15                    2,97                    13,25
3               0,02                    2,9                     13,25
4               0,05                    2,8                     13,12
EntityFramework Results
Run #   Player by ID            Players per Team                Teams per Sport
0               0,01                    2,27                    28,38
1               0,01                    2,4                     28,25
2               0                       2,13                    28,5
3               0,01                    2,17                    27,5
4               0,01                    2,13                    29
ADONET Results
Run #   Player by ID            Players per Team                Teams per Sport
0               0                       2,03                    11,75
1               0                       2                       12,62
2               0                       2                       11,38
3               0                       2                       12,38
4               0                       2                       11,25

/EDIT 我已经将 ADO.NET 时间添加到结果列表中作为引用。

我的问题是:由于加载时间如此不同,我的查询是否有问题?

在我运行的真实世界系统中,我已将我所有的异步数据库调用更改为同步调用,而且我在统计数据中看到的是,系统的数据库调用速度提高了约 50% .这是一个有 100-120 个当前用户通过 SignalR 连接的系统,它的数据库非常繁重。

最佳答案

我认为this article详细解释。

Async 并不更快,并且在正常的“同步”代码之上增加了很多开销。但它允许在您浪费时间等待的情况下更好地使用资源(例如网络连接的高延迟等)

关于c# - Entity Framework 6 异步方法与同步方法的性能,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/40423997/

相关文章:

javascript - javascript中for循环内的异步函数调用

c# - 错误 : Could not load file or assembly 'System.Net.Http.Primitives, Version=1.5.0.0...'

entity-framework - Entity Framework ——如何使用实体关联?

C# 如何通过向它添加属性来扩展存在于不同 dll 中的类?

entity-framework - 如何强制 Entity Framework 不锁定数据库

c# - 我实际上如何从方法外部获得异步 Web 请求的响应?

选择/轮询与异步 I/O 的性能

c# - Selenium 与 UWP 应用程序?

javascript - 为什么 C# 和 ECMAScript ISO 标准可以免费获得,而 C/C++ 却不能?

c# - WinRT 将 Jpg 或 PNG 转换为 GIF