有谁知道如何覆盖 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 memberSystem.Data.Entity.DbContext.SaveChangesAsync()
最佳答案
EF 6(不是 EF Core 6):
DbContext.SaveChangesAsync
方法有两个独立的虚拟
重载:SaveChangesAsync()
SaveChangesAsync(CancellationToken)
。
- 默认情况下,无参数
SaveChangesAsync()
重载只是通过传递CancellationToken.None)
调用SaveChangesAsync(CancellationToken)
。 - 因此默认情况下您只需要覆盖
SaveChangesAsync(CancellationToken)
重载。 - 但是,如果您想绝对确定,您应该覆盖
SaveChangesAsync()
并使其密封
,因此DbContext
的任何进一步子类都有一个明确的单一方法来重载。
EF 核心 5:
DbContext.SaveChangesAsync
方法有两个单独的virtual
重载,但与旧版 EF 6 相比,它们具有不同的签名。- 主要区别在于
cancellationToken
现在是所有重载中的可选参数。
SaveChangesAsync(CancellationToken cancellationToken = default)
SaveChangesAsync(bool acceptAllChangesOnSuccess,CancellationToken cancellationToken = default)
。
- 主要区别在于
重载 async
方法时要注意:
- 您可能需要添加
async
修饰符,否则您无法使用await
运算符。 - 当使用 Visual Studio 的方法 stub 生成器时(当您在键入
override
后使用 Tab 按钮自动插入 stub 时)它将缺少async
修饰符。 - 但是,如果您的重载只是“转发”到另一个异步方法或
base
实现,那么您可以简单地执行return base.MyMethodAsync()
,但是 如果该方法需要在其他方法返回和您的覆盖方法返回之间执行某事,则永远不要执行此操作。- 我预计最常见的情况是当您需要
using
或try
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/