gpt4 book ai didi

c# - EF4.1 代码优先 DbContext : The operation cannot be completed because the DbContext has been disposed

转载 作者:太空宇宙 更新时间:2023-11-03 11:16:53 27 4
gpt4 key购买 nike

我有一个直接调用的 Controller 操作,但抛出了这个错误:

The operation cannot be completed because the DbContext has been disposed.

我只在网上找到了有关延迟执行的解决方案,但我认为这不适用于此处,因为我在任何地方使用上下文(在本例中)我都调用 .ToList().FirstOrDefault()。这是我的代码:

Controller 内容

    private IUnitOfWork UnitOfWork;
public MyFavouritesController(
IAccountServices accountServices,
IUnitOfWork unitOfWork
)
{
AccountServices = accountServices;
UnitOfWork = unitOfWork;
}

public ActionResult Index()
{
int? id = AccountServices.GetCurrentUserId();
if (!id.HasValue)
{
return RedirectToAction("Login", "Account", new { ReturnUrl = this.HttpContext.Request.Url.AbsolutePath });
}
var user = UnitOfWork.UserRepo.Get(id.Value, "Favourites", "Favourites.County", "Favourites.Country");
//THE ABOVE CALL GETS THE ERROR

//.....
return View();
}

存储库基类

public class RepositoryBase<C, T> : IDisposable
where C:DbContext, new()
where T : ModelBase
{
private DbContext _context;
public DbContext Context
{
get
{
if (_context == null)
{
_context = new C();
this.AllowSerialization = true;
}
return _context;
}
set
{
_context = value;
}
}

public virtual T Get(int Id, params string[] includes)
{
if (Id > 0)
{
var result = Context.Set<T>().Where(t => t.Id == Id);
foreach (string includePath in includes)
{
result = result.Include(includePath);
}
return result.FirstOrDefault(); //This is where the error occurs.
}
else
{
throw new ApplicationException("Id is zero (0).");
}
}

//... (More CRUD methods)

public void Dispose()
{
if (Context != null)
{
Context.Dispose(); //Debugger never hits this before the error
}
}
}

工作类单元

public class UnitOfWork:IUnitOfWork
{
public UnitOfWork(
//... DI of all repos
IUserRepository userRepo
)
{
//... save repos to an local property
UserRepo = userRepo;

//create a new instance of the context so that all the repo's have access to the same DbContext
Context = new Context();

//assign the new context to all the repo's
//...
UserRepo.Context = Context;
}

public Context Context { get; set; }

public IUserRepository UserRepo { get; set; }

//... (some more repositories)

public void Dispose()
{
Context.Dispose(); //THIS IS NOT HIT AT ALL
}
}

最后,模型容器有这条线

_Instance.RegisterType<IUnitOfWork, UnitOfWork>(new PerThreadLifetimeManager());

如您所见,索引操作将接收一个新的 UnitOfWork 实例,其中包含一个新的 DbContext 对象。但是在第一次调用此上下文时,它会抛出上述错误。这种模式适用于我的代码中的任何其他地方。

谢谢

更新

下面的答案是使用 perRequestLifetimeManager。下面是 one in unity 的实现:

    public class HttpRequestLifetimeManager : LifetimeManager
{
private string _key = Guid.NewGuid().ToString();

public override object GetValue()
{
if (HttpContext.Current != null && HttpContext.Current.Items.Contains(_key))
return HttpContext.Current.Items[_key];
else
return null;
}

public override void RemoveValue()
{
if (HttpContext.Current != null)
HttpContext.Current.Items.Remove(_key);
}

public override void SetValue(object newValue)
{
if (HttpContext.Current != null)
HttpContext.Current.Items[_key] = newValue;
}
}

最佳答案

我注意到您正在使用 PerThreadLifetimeManager 来控制您的工作单元类的创建和处置。如果您的 IoC 容器支持,您可能应该将其更改为类似 PerRequestLifetimeManager 的内容。

关于c# - EF4.1 代码优先 DbContext : The operation cannot be completed because the DbContext has been disposed,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/12424997/

27 4 0