c# - 覆盖 SaveChangesAsync

标签 c# asp.net entity-framework

有谁知道如何覆盖 SaveChangesAsync?我知道有人发布了类似的问题,但没有答案。我在下面有以下代码:

public override async Task<int> SaveChangesAsync()
{
    PerformFurtherValidations();
    return await base.SaveChangesAsync();
}

在构建期间,我收到以下错误消息:

Error SaveChangesAsync(): return type must be System.Threading.Tasks.Task<int> to match overridden member System.Data.Entity.DbContext.SaveChangesAsync()

最佳答案

  • EF 6(不是 EF Core 6):

    • DbContext.SaveChangesAsync 方法有两个独立的虚拟 重载:
      1. SaveChangesAsync()
      2. SaveChangesAsync(CancellationToken)
    • 默认情况下,无参数 SaveChangesAsync() 重载只是通过传递 CancellationToken.None) 调用 SaveChangesAsync(CancellationToken)
    • 因此默认情况下您只需要覆盖 SaveChangesAsync(CancellationToken) 重载。
    • 但是,如果您想绝对确定,您应该覆盖SaveChangesAsync() 使其密封 ,因此 DbContext 的任何进一步子类都有一个明确的单一方法来重载。
  • EF 核心 5:

    • DbContext.SaveChangesAsync 方法有两个单独的 virtual 重载,但与旧版 EF 6 相比,它们具有不同的签名。
      • 主要区别在于 cancellationToken 现在是所有重载中的可选参数。
      1. SaveChangesAsync(CancellationToken cancellationToken = default)
      2. SaveChangesAsync(bool acceptAllChangesOnSuccess,CancellationToken cancellationToken = default)

重载 async 方法时要注意:

  • 您可能需要添加 async 修饰符,否则您无法使用 await 运算符。
  • 当使用 Visual Studio 的方法 stub 生成器时(当您在键入 override 后使用 Tab 按钮自动插入 stub 时)它将缺少 async修饰符。
  • 但是,如果您的重载只是“转发”到另一个异步方法或 base 实现,那么您可以简单地执行 return base.MyMethodAsync(),但是 如果该方法需要在其他方法返回和您的覆盖方法返回之间执行某事,则永远不要执行此操作。
    • 我预计最常见的情况是当您需要 usingtry block 来释放资源时仅在其他方法之后完成,但如果您不在 using block 内使用 await,则 .Dispose 方法将在之前 任务 完成。
  • 并且不要忘记始终将 .ConfigureAwait(false) 添加到所有 await 语句中(除非您绝对知道您在做什么做 w.r.t 同步上下文)。

EF 6:

// This method is sealed and forwards to `SaveChangesAsync(CancellationToken)`, so any further subclasses only need to override a single `SaveChangesAsync` method instead of 2.
// Also note it lacks the `async` modifier, so you cannot use the `await` operator.
public sealed override Task<int> SaveChangesAsync()
{
    return this.SaveChangesAsync(cancellationToken);
}

// This method has the `async` modifier, so `await` can be used:
public override async Task<int> SaveChangesAsync(CancellationToken cancellationToken)
{
    return await base.SaveChangesAsync(cancellationToken).ConfigureAwait(false);
}

EF 核心 5:

public sealed override Task<int> SaveChangesAsync(CancellationToken cancellationToken = default)
{
    return this.SaveChangesAsync(acceptAllChangesOnSuccess: true, cancellationToken);
}

public override async Task<int> SaveChangesAsync(bool acceptAllChangesOnSuccess, CancellationToken cancellationToken = default)
{
    return await base.SaveChangesAsync(true, cancellationToken).ConfigureAwait(false);
}

关于c# - 覆盖 SaveChangesAsync,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/26001151/

相关文章:

c# - 组合返回和切换

c# - "multi-threadedly"在 async/await 模式下实际上执行了什么代码?

c# - 在 MigraDoc 表中插入 "http"图像

c# - 覆盖 AspNetCore.Identity 表中的默认索引

c# - 数据库双连接关系插入问题

entity-framework - 如何首先在 EF 4.1 代码中映射父列

asp.net-mvc - SimpleMemership CreateUserAndAccount 自定义

c# - 如何处理 FileHelper 类中 SQLDecimal 数据类型的空值

asp.net - 用户被随机注销,显示奇怪的网址,用户无法登录,直到缓存清除或重新启动

asp.net - 如何更改自定义 TextBox 控件的 'type' 属性