gpt4 book ai didi

c# - 多次调用时出现“DbContext 已处理错误”

转载 作者:太空宇宙 更新时间:2023-11-03 23:03:55 24 4
gpt4 key购买 nike

我已经设置了一个具有简单 getCustomers() 方法的 API。端点在第一次调用时返回数据,但在第二次调用时返回错误。

Error: The operation cannot be completed because the DbContext has been disposed

错误是在 return db.Customers... 上我的 CustomerService 中引起的。

Question: Why does this work on the first call, but fail on the second call. How can this be resolved?

可在此处找到 GitHub 存储库: https://github.com/ChaseHardin/MyBookStore

下面是代码的演练:

Controller :

[RoutePrefix("api/customers")]
public class CustomerController : ApiController
{
private readonly CustomerService _service = new CustomerService();

[HttpGet, Route("")]
public virtual IHttpActionResult Get()
{
var customers = _service.GetCustomers();
return Ok(new {customers});
}
}

客户服务:

public class CustomerService : BaseService
{
public List<CustomerViewModel> GetCustomers()
{
using (var db = Application.GetDatabaseInstance())
{
return db.Customers.Select(AutoMapper.Mapper.Map<CustomerViewModel>).ToList();
}
}
}

基础服务

public class BaseService
{
public BaseService()
{
AutoMapperConfiguration();
}

public void AutoMapperConfiguration()
{
Assembly.GetExecutingAssembly()
.GetTypes()
.Where(x => x.IsClass && x.Namespace == "MyBookStore.Business.ViewModels")
.ForEach(x => System.Runtime.CompilerServices.RuntimeHelpers.RunClassConstructor(x.TypeHandle));

AutoMapper.Mapper.CreateMap<bool, short?>().ConvertUsing(x => x ? (short)1 : (short)0);
AutoMapper.Mapper.CreateMap<short, bool>().ConvertUsing(x => x == 1);

AutoMapper.Mapper.CreateMap<bool, int?>().ConvertUsing(x => x ? 1 : 0);
AutoMapper.Mapper.CreateMap<int?, bool>().ConvertUsing(x => x.HasValue && x.Value == 1);

AutoMapper.Mapper.CreateMap<short, int>().ConvertUsing(x => (int)x);
AutoMapper.Mapper.CreateMap<int, int?>().ConvertUsing(x => x);
}
}

CustomerViewModel

public class CustomerViewModel
{
static CustomerViewModel()
{
AutoMapper.Mapper.CreateMap<Customer, CustomerViewModel>().ReverseMap();
}

public Guid CustomerId { get; set; }
public string FirstName { get; set; }
public string LastName { get; set; }
}

上下文设置:

public class Application
{
private static readonly MyBookStoreEntity Context = new MyBookStoreEntity();

public static MyBookStoreEntity GetDatabaseInstance()
{
return Context;
}
}

最佳答案

当您使用 using block 时:

using (var db = Application.GetDatabaseInstance())

被“使用”的对象将被放置在 block 的末尾。 (using 基本上是 try/finally 的语法速记,其中 finally block 调用 .Dispose()对象。)

你“使用”的是这个值:

private static readonly MyBookStoreEntity Context = new MyBookStoreEntity();

此值为static,因此每次调用时都是MyBookStoreEntity 的同一个实例。但是当你第一次调用它时,你 .Dispose() 它。因此,任何后续调用都将针对已处置的对象。

基本上,您已经发现了为什么静态 数据库上下文是一个非常坏主意的原因之一。您仍然可以像现在一样将数据库上下文封装到一个方法中,但每次都要让该方法返回一个新实例:

public static MyBookStoreEntity GetDatabaseInstance()
{
return new MyBookStoreEntity();
}

或者,如果此时该方法没有真正提供任何好处,则只需在您需要的地方创建上下文:

using (var db = new MyBookStoreEntity())

创建数据库上下文并不是一项特别繁重的操作。但是当你不使用它们时把它们放在身边是。 (在不同的操作之间共享它们充满了危险。)一个好的经验法则是离散地定义您需要为给定的应用程序操作执行的数据库操作,并在尽可能紧凑的代码中创建/使用/处置您的数据库连接尽可能阻止这些操作。

关于c# - 多次调用时出现“DbContext 已处理错误”,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/42035249/

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