C# “System.ObjectDisposedException”类型的异常

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/11648504/
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-09 18:39:47  来源:igfitidea点击:

Exception of type 'System.ObjectDisposedException'

c#.netentity-frameworkef-code-first

提问by LCJ

I have following EF code first code. It is working fine. But when I look for the value of 'club2.Members', it says following:

我有以下 EF 代码第一个代码。它工作正常。但是当我寻找 'club2.Members' 的值时,它说如下:

'club2.Members' threw an exception of type 'System.ObjectDisposedException'.

“club2.Members”引发了“System.ObjectDisposedException”类型的异常。

Message is:

讯息是:

The ObjectContext instance has been disposed and can no longer be used for operations that require a connection.

ObjectContext 实例已被释放,不能再用于需要连接的操作。

I have not set value for Members property. That's okay. However it should not cause any exception internally.

我没有为成员属性设置值。没关系。但是,它不应在内部引起任何异常。

  1. Is there a way to overcome this exception?
  2. Does removal of this exception help in improving performance?
  3. Why this exception did not cause termination of program execution?
  1. 有没有办法克服这个异常?
  2. 删除此异常是否有助于提高性能?
  3. 为什么这个异常没有导致程序执行终止?

Note: I don't need the Members data in club entity (at the point where I have called). Even there is no members added to the club at that time. All i need is to get rid of the exception; not to load data using eager load. How to avoid the exception?

注意:我不需要俱乐部实体中的会员数据(在我打电话的时候)。甚至当时还没有加入俱乐部的成员。我所需要的就是摆脱异常;不要使用预先加载来加载数据。如何避免异常

enter image description here

在此处输入图片说明

namespace LijosEF
{

public class Person
{
    public int PersonId { get; set; }
    public string PersonName { get; set; }
    public virtual ICollection<Club> Clubs { get; set; }
}

public class Club 
{
    public int ClubId { get; set; }
    public string ClubName { get; set; }
    public virtual ICollection<Person> Members { get; set; }

}




//System.Data.Entity.DbContext is from EntityFramework.dll
public class NerdDinners : System.Data.Entity.DbContext
{

    public NerdDinners(string connString): base(connString)
    { 

    }

    protected override void OnModelCreating(DbModelBuilder modelbuilder)
    {
         //Fluent API - Plural Removal
        modelbuilder.Conventions.Remove<PluralizingTableNameConvention>();
    }

    public DbSet<Person> Persons { get; set; }
    public DbSet<Club> Clubs { get; set; }



}
}




    static void Main(string[] args)
    {
        Database.SetInitializer<NerdDinners>(new MyInitializer());

        CreateClubs();
        CreatePersons();

    }

    public static void CreateClubs()
    {

        string connectionstring = "Data Source=.;Initial Catalog=NerdDinners;Integrated Security=True;Connect Timeout=30";
        using (var db = new NerdDinners(connectionstring))
        {

            Club club1 = new Club();
            club1.ClubName = "club1";

            Club club2 = new Club();
            club2.ClubName = "club2";

            Club club3 = new Club();
            club3.ClubName = "club3";

            db.Clubs.Add(club1);
            db.Clubs.Add(club2);
            db.Clubs.Add(club3);

            int recordsAffected = db.SaveChanges();


        }
    }

    public static Club GetClubs(string clubName)
    {
        string connectionstring = "Data Source=.;Initial Catalog=NerdDinners;Integrated Security=True;Connect Timeout=30";
        using (var db = new NerdDinners(connectionstring))
        {

            var query = db.Clubs.SingleOrDefault(p => p.ClubName == clubName);
            return query;
        }
    }

    public static void CreatePersons()
    {
        string connectionstring = "Data Source=.;Initial Catalog=NerdDinners;Integrated Security=True;Connect Timeout=30";
        using (var db = new NerdDinners(connectionstring))
        {

            Club club1 = GetClubs("club1");
            Club club2 = GetClubs("club2");
            Club club3 = GetClubs("club3");

             //More code to be added (using db) to add person to context and save
        }
    }

采纳答案by LCJ

APPROACH 1

方法一

There is no need for the following method. This can be done in the present context. It is only a select.

不需要下面的方法。这可以在当前上下文中完成。它只是一个选择。

GetClubs("club1");

APPROACH 2

方法 2

Attaching the entities resolved the problem:

附加实体解决了问题:

            Club club1 = GetClubs("club1");
            Club club2 = GetClubs("club2");
            Club club3 = GetClubs("club3");

            ((IObjectContextAdapter)db).ObjectContext.Attach((IEntityWithKey)club1);
            ((IObjectContextAdapter)db).ObjectContext.Attach((IEntityWithKey)club2);
            ((IObjectContextAdapter)db).ObjectContext.Attach((IEntityWithKey)club3);


            var test = club2.Members;

I should not have tried to refer club2.Members (of Club class), since it is not needed for creating Person object.

我不应该尝试引用 club2.Members(属于 Club 类),因为创建 Person 对象不需要它。

Members is related data in Club class. Since it is virtual, it will do lazy loading.

Member 是 Club 类中的相关数据。由于它是虚拟的,它将进行延迟加载。

In a different scenario, if I had to retrieve Members object (which is a related data) from a different context, I should rely on eager loading (in the place which provides you with Club object).

在不同的场景中,如果我必须从不同的上下文中检索 Members 对象(这是一个相关数据),我应该依赖于预先加载(在为您提供 Club 对象的地方)。

Refer following also:

另请参阅以下内容:

  1. Entity Framework: Duplicate Records in Many-to-Many relationship

  2. System.ObjectDisposedException: The ObjectContext instance has been disposed and can no longer be used for operations that require a connection

  3. The ObjectContext instance has been disposed and can no longer be used for operations that require a connection

  4. ObjectContext instance has been disposed while binding

  1. 实体框架:多对多关系中的重复记录

  2. System.ObjectDisposedException: ObjectContext 实例已被释放,不能再用于需要连接的操作

  3. ObjectContext 实例已被释放,不能再用于需要连接的操作

  4. 绑定时 ObjectContext 实例已被释放

回答by Amiram Korach

You're getting this error because you are disposing the dbcontext after you execute the query. If you want to use the data in "members" then load it with the query: http://blogs.msdn.com/b/adonet/archive/2011/01/31/using-dbcontext-in-ef-feature-ctp5-part-6-loading-related-entities.aspx

您收到此错误是因为您在执行查询后处理了 dbcontext。如果要使用“成员”中的数据,请使用查询加载它:http: //blogs.msdn.com/b/adonet/archive/2011/01/31/using-dbcontext-in-ef-feature- ctp5-part-6-loading-related-entities.aspx

If you don't need lazy loading, which means that only data you're loading in the query is loaded (this will eliminate the exception), set LazyLoadingEnabled = false. Look here: Disable lazy loading by default in Entity Framework 4

如果您不需要延迟加载,这意味着只加载您在查询中加载的数据(这将消除异常),请设置 LazyLoadingEnabled = false。看这里: 在 Entity Framework 4 中默认禁用延迟加载