C# DbContext 已被释放

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/18635508/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-10 12:48:52  来源:igfitidea点击:

DbContext has been disposed

c#asp.netasp.net-mvcentity-frameworkdbcontext

提问by Ali Esfahani

I developed a web application with ASP.NET MVC 4 and SQL Server 2008, I create ContextManager class to have only one database context in all pages.

我使用 ASP.NET MVC 4 和 SQL Server 2008 开发了一个 Web 应用程序,我创建了 ContextManager 类以在所有页面中只有一个数据库上下文。

public static class ContextManager
{
    public static HotelContext Current
    {
        get
        {
            var key = "Hotel_" + HttpContext.Current.GetHashCode().ToString("x")
                      + Thread.CurrentContext.ContextID.ToString();
            var context = HttpContext.Current.Items[key] as HotelContext;
            if (context == null)
            {
                context = new HotelContext();
                HttpContext.Current.Items[key] = context;
            }
            return context;
        }
    }
}

It works properly in most of the pages, but in registration page something goes wrong and my context gone deposed with following error:

它在大多数页面中都能正常工作,但在注册页面中出现问题,我的上下文因以下错误而被废止:

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

操作无法完成,因为 DbContext 已被释放。

public ActionResult Register ( RegisterModel model )
{
    if ( ModelState.IsValid )
    {
        // Attempt to register the user
        try
        {
            WebSecurity.CreateUserAndAccount( model.UserName, model.Password,
                                              new
                                               {
                                                      Email = model.Email,
                                                      IsActive = true,
                                                      Contact_Id = Contact.Unknown.Id
                                               } );

            //Add Contact for this User.
            var contact = new Contact { Firstname = model.FirstName, LastName = model.Lastname };
            _db.Contacts.Add( contact );
            var user = _db.Users.First( u => u.Username == model.UserName );
            user.Contact = contact;
            _db.SaveChanges();
            WebSecurity.Login( model.UserName, model.Password );

at the line _db.Contacts.Add( contact );I got the exception.

在这条线上_db.Contacts.Add( contact );我得到了例外。

But without using ContextManager by changing

但不通过更改使用 ContextManager

HotelContext _db = ContextManager.Current;

into:

进入:

HotelContext _db = new HotelContext();

the problem was solved. But I need to use my own ContextManager. What is the problem?

问题解决了。但我需要使用我自己的 ContextManager。问题是什么?

采纳答案by ken2k

Your context has been disposed somewhere else (not in the code you've shown), so basically when you access it from your Registeraction, it throws the exception.

您的上下文已被处理到其他地方(不在您显示的代码中),因此基本上当您从Register操作中访问它时,它会引发异常。

Actually, you shouldn't use a static singleton to access to your context. Do instantiate a new DbContextinstance for each request. See c# working with Entity Framework in a multi threaded server

实际上,您不应该使用静态单例来访问您的上下文。为每个请求实例化一个新DbContext实例。请参阅在多线程服务器中使用实体框架的 c#

回答by Henk Mollema

You are probably 'lazy-loading' a navigation property of Userin your registration view. Make sure you include it by using the Includemethod on your DbSetbefore sending it to the view:

您可能正在“延迟加载”User注册视图中的导航属性。在将它发送到视图之前,请确保使用Include您的方法包含它DbSet

_db.Users.Include(u => u.PropertyToInclude);

Also, sharing DbContexts with a static property may have unexpected side effects.

此外,DbContext与静态属性共享s 可能会产生意想不到的副作用。

回答by Dhanik Lal Sahni

In my case, my GetAll method was not calling ToList() method after where clause in lambda expression. After using ToList() my problem was solved.

就我而言,我的 GetAll 方法没有在 lambda 表达式中的 where 子句之后调用 ToList() 方法。使用 ToList() 后,我的问题解决了。

Where(x => x.IsActive).ToList();

回答by GreatNews

I used to have the same problem. I solved it doing as it was said above. Instantiate a new instance of your context.

我曾经有同样的问题。我按照上面说的那样解决了它。实例化上下文的新实例。

Try using this:

尝试使用这个:

            using (HotelContextProductStoreDB = new ProductStoreEntities())
            {
                //your code
            }

This way it'll be created a new instance everytime you use your code and your context will not be disposed.

这样,每次使用代码时都会创建一个新实例,并且不会处理上下文。

回答by antonio

Why override the Dispose(bool)?

为什么要覆盖 Dispose(bool)?

public partial class HotelContext : DbContext
{
    public bool IsDisposed { get; set; }
    protected override void Dispose(bool disposing)
    {
        IsDisposed = true;
        base.Dispose(disposing);
    }
}

And, then check IsDisposed

然后检查 IsDisposed

public static class ContextManager
{
    public static HotelContext Current
    {
        get
        {
            var key = "Hotel_" + HttpContext.Current.GetHashCode().ToString("x")
                      + Thread.CurrentContext.ContextID.ToString();
            var context = HttpContext.Current.Items[key] as HotelContext;
            if (context == null || context.IsDisposed)
            {
                context = new HotelContext();
                HttpContext.Current.Items[key] = context;
            }
            return context;
        }
    }
}

Maybe, can be an option.

也许,可以是一种选择。