内存数据库不保存数据

我有一个简单的web应用程序,在客户端有角度,在服务器端有asp.net核心web-api。 我使用InMemoryDatabase

services.AddDbContext(options => options.UseInMemoryDatabase("ItemsDB")); 

存储数据以简化开发。 但我遇到了一个问题。 我在web-api上有一个控制器来响应用户的请求:

 [Route("api/[controller]")] public class ItemsController : Controller { private readonly IApiService apiService; public ItemsController(IApiService apiService)//using DI from Startup.cs { this.apiService = apiService; } [HttpPost, Route("addItem")] public async Task Add([FromBody]Item item) { return await apiService.Add(item); } [HttpDelete("{id}")] public async Task Delete(int id) { return await apiService.Delete(id); } [HttpPut] public async Task Put([FromBody]Item item) { return await apiService.Put(item); } } 

以及以下Startup.cs配置:

 public void ConfigureServices(IServiceCollection services) { services.AddMvc(); services.AddDbContext(options => options.UseInMemoryDatabase("ItemsDB")); services.AddSingleton(provider => { var context = services.BuildServiceProvider().GetService(); return new UnitOfWork(context); }); services.AddSingleton(provider => { return new ApiService(services); }); } 

问题是,当我添加新项目时,一切都很好……但是我发布了另一个删除此项目的请求,它可能会显示没有这样的项目或有时可能会删除它…所以换句话说,数据库存在然后消失,我不知道什么时候。 这是一些参考上面的附加代码

 public class ApiService: IApiService { private readonly IUnitOfWork database; private readonly IServiceProvider provider; public ApiService(IServiceCollection serviceCollection) { provider = serviceCollection.BuildServiceProvider(); } public IUnitOfWork Database { get { return provider.GetService(); } } public async Task Add(Item item) { Database.Items.Add(item); await Database.SaveAsync(); var id = Database.Items.LastItem().Id; return new Response() { Result = true, ItemId = id }; } public async Task Delete(int id) { var item = await db.Items.Find(id); Database.Items.Remove(item); await Database.SaveAsync(); return new Response() { Result = true }; } public async Task Put(Item item) { Database.Items.Update(item); await Database.SaveAsync(); return new Response() { Result = true }; } } 

更新:UnitOfWork实施:

  public class UnitOfWork: IUnitOfWork { private readonly DbContext context; private IRepository itemsRepository; public UnitOfWork(DbContext dbContext) { context = dbContext; } public IRepository Items { get { return itemsRepository ?? (itemsRepository = new Repository(context)); } } public void Dispose() { context.Dispose(); } public void Save() { context.SaveChanges(); } public async Task SaveAsync() { await context.SaveChangesAsync(); } } 

你的代码有很多严重的问题,让我们来看看。

  1. services.AddDbContext添加了一个Scoped服务,这意味着将在每个请求上创建和处理实例。 services.AddSingleton添加了一个Singleton服务,因此只会创建一个实例。 您不能将作用域服务添加到单例服务,因为单例服务使用的引用将被处置,您将最终得到已处置的上下文。
  2. 这段代码:

     return provider.GetService(); 

    表示服务定位器反模式。 你可以猜到,反模式是你想要避免的。 我也不知道为什么你会想要一个服务来构建整个DI容器,也不知道为什么你希望服务有责任获得它自己需要的依赖。

  3. 这部分是您的问题实际来自的地方:

     Database.SaveAsync(); 

    您正在调用异步函数,而不是await它完成。 任务可能完成与否,它可能会抛出错误,你永远不会知道发生了什么。

最好的办法是,如果人们停止尝试在另一个工作单元和存储库上创建工作单元+存储库模式那么所有这些都可以避免。 entity framework核心已经实现了这些:

 DbContext => Unit of Work DbSet => Repository (generic) 

你为什么还想要另一种抽象? 您是否真的会从项目中丢弃EF Core来certificate代码的维护成本?

整个问题代码可能是这样的:

 [Route("api/[controller]")] public class ItemsController : Controller { private readonly YourContext _context; public ItemsController(YourContext context) { _context = context; } [HttpPost] public async Task Add([FromBody]Item item) { context.Items.Add(item); await context.SaveChangesAsync(); return Ok(item.Id); } [HttpDelete("{id}")] public async Task Delete(int id) { context.Items.Remove(item); await context.SaveChangesAsync(); return Ok(); } [HttpPut] public async Task Put([FromBody]Item item) { context.Items.Update(item); await context.SaveChangesAsync(); return Ok(); } }