gpt4 book ai didi

c# - 内存数据库不保存数据

转载 作者:太空宇宙 更新时间:2023-11-03 19:42:52 25 4
gpt4 key购买 nike

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

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

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

[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<Response> Add([FromBody]Item item)
{
return await apiService.Add(item);
}

[HttpDelete("{id}")]
public async Task<Response> Delete(int id)
{
return await apiService.Delete(id);
}

[HttpPut]
public async Task<Response> Put([FromBody]Item item)
{
return await apiService.Put(item);
}
}

以及以下 Startup.cs 配置:

public void ConfigureServices(IServiceCollection services)
{
services.AddMvc();
services.AddDbContext<ItemsContext>(options => options.UseInMemoryDatabase("ItemsDB"));
services.AddSingleton<IUnitOfWork, UnitOfWork>(provider => {
var context = services.BuildServiceProvider().GetService<ItemsContext>();
return new UnitOfWork(context);
});
services.AddSingleton<IApiService, ApiService>(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<IUnitOfWork>();
}
}

public async Task<Response> 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<Response> 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<Response> Put(Item item)
{
Database.Items.Update(item);
await Database.SaveAsync();
return new Response() { Result = true };
}
}

更新:工作单元实现:

 public class UnitOfWork: IUnitOfWork
{
private readonly DbContext context;
private IRepository<Item> itemsRepository;

public UnitOfWork(DbContext dbContext)
{
context = dbContext;
}

public IRepository<Item> Items
{
get
{
return itemsRepository ?? (itemsRepository = new Repository<Item>(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<IUnitOfWork>();

代表服务定位器反模式。您可以猜到,反模式是您想要避免的。我也不知道为什么您想要一个服务来构建整个 DI 容器,也不知道为什么您想要一个服务负责获取它自己需要的依赖项.

  1. 这部分是您的问题实际来源:

     Database.SaveAsync();

您正在调用一个异步函数,而不是等待它完成。任务可能完成也可能不完成,可能抛出错误也可能不抛出错误,你永远不知道发生了什么。

最好的事情是,如果人们停止尝试创建一个工作单元 + 存储库模式而不是另一个工作单元和存储库,那么所有这些都是可以避免的。 Entity Framework Core 已经实现了这些:

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

为什么你需要另一个抽象?您真的会从项目中丢弃 EF Core 以证明代码的维护成本合理吗?

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

[Route("api/[controller]")]
public class ItemsController : Controller
{
private readonly YourContext _context;

public ItemsController(YourContext context)
{
_context = context;
}

[HttpPost]
public async Task<IActionResult> Add([FromBody]Item item)
{
context.Items.Add(item);
await context.SaveChangesAsync();

return Ok(item.Id);
}

[HttpDelete("{id}")]
public async Task<IActionResult> Delete(int id)
{
var item = await context.Items.FindAsync(id);
context.Items.Remove(item);
await context.SaveChangesAsync();

return Ok();
}

[HttpPut]
public async Task<IActionResult> Put([FromBody]Item item)
{
context.Items.Update(item);
await context.SaveChangesAsync();

return Ok();
}
}

关于c# - 内存数据库不保存数据,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/50457007/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com