这是我到目前为止无法运行的代码。我已经完成了我的理解允许的所有研究。 我可能会错过一些愚蠢的东西。我是 c# 和 .Net 环境的新手。
LibraryContext 类一切都很好。问题是我无法使用该界面。当我将其作为服务加载到 Startup.cs 中,然后在控制器中调用它时,会出现错误。使用
Startup.cs
和 BooksController.cs
片段更新问题。
第一个错误位于
LibraryContext.cs
:
LibraryContext' does not implement interface member 'ILibraryContext.SaveChangesAsync()' [LibraryApi].
然后在
BooksController.cs
:
'ILibraryContext' does not contain a definition for 'Entry' and no accessible extension method 'Entry' accepting a first argument of type 'ILibraryContext' could be found (are you missing a using directive or an assembly reference?) [LibraryApi]csharp(CS1061)
...
LibraryContext.cs
public interface ILibraryContext : IDisposable
{
public DbSet<Reader> Readers { get; set; }
public DbSet<Book> Books { get; set; }
Task<int> SaveChangesAsync();
}
public class LibraryContext : DbContext, ILibraryContext
{
public LibraryContext(DbContextOptions<LibraryContext> options)
: base(options)
{
}
public virtual DbSet<Reader> Readers { get; set; }
public virtual DbSet<Book> Books { get; set; }
protected override void OnModelCreating(ModelBuilder modelBuilder)
{
modelBuilder.Entity<Book>().ToTable("Book");
modelBuilder.Entity<Reader>().ToTable("Reader");
}
}
Startup.cs
{
services.AddScoped<ILibraryContext>(provider => provider.GetService<LibraryContext>());
...
}
BooksController.cs
{
private readonly ILibraryContext _context;
public BooksController(ILibraryContext context)
{
_context = context;
}
...
不,“LibraryContext”类并不是一切都很好。线索就在错误消息中:
LibraryContext' does not implement interface member 'ILibraryContext.SaveChangesAsync()'
。
您可以这样添加:
async Task<int> SaveChangesAsync() => await base.SaveChangesAsync();
或
async Task<int> SaveChangesAsync() => base.SaveChangesAsync();
您可能期望基类
SaveChangesAsync
中的 DbContext
能够履行接口契约,但接口并不是这样工作的。
您可以在
SaveChangesAsync
中添加 LibraryContext
的实现,它只调用 base.SaveChangesAsync
并返回其结果,从而履行接口契约。
为了扩展 Johan Donne 的答案,在我的
DbContext
中,我总是用 包裹
SaveChangesAsync
public async Task<int> TrySaveAsync(string message = null, bool clearChangeTracker = true)
{
try
{
return await SaveChangesAsync();
}
catch (Exception e)
{
if(clearChangeTracker) ChangeTracker.Clear();
//do your exception handling here
return -1;
}
}
所以你可以让这个电话成为你的
interface
的一部分:
Task<int> TrySaveAsync(string message = null, bool clearChangeTracker = true);
然后在我的
Controller
或任何地方,如果受影响的行数是-1
,我就知道出了问题,并且可以根据当前的需求进行处理。