2012-07-25 114 views
3

我有以下EF代码第一个代码。它工作正常。但是,当我查看'club2.Members'的价值时,它会显示以下内容:类型'System.ObjectDisposedException'的异常

'club2.Members'抛出了'System.ObjectDisposedException'类型的异常。

消息是:

的ObjectContext的实例已被设置,并且不再能够用于需要连接的操作。

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

  1. 有没有办法克服这个异常?
  2. 删除此异常是否有助于提高性能?
  3. 为什么这个异常不会导致程序执行终止?

注意:我不需要俱乐部实体中的会员数据(在我打电话的地方)。即使当时没有成员加入俱乐部。我需要的是摆脱例外;不要使用热切加载来加载数据。如何避免异常

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 
     } 
    } 
+0

我刚刚忽略了你的代码。为什么在CheckValues中创建另一个数据库实例? – 2012-07-26 07:35:50

+0

@AmiramKorach我有另一种方法 - CreatePersons。我将不得不在那里使用新的环境。我正在使用Context Per Request方法。人们需要了解俱乐部。 – Lijo 2012-07-26 08:05:27

+0

这段代码没有意义。您在CreatePersons中根本不使用数据库变量。每个GetClubs调用都使用自己的数据库变量。 – 2012-07-26 08:12:33

回答

0

方法1

没有必要对下面的方法。这可以在目前的情况下完成。这只是一个选择。

GetClubs("club1"); 

方法2

附加实体解决了这个问题:

  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; 

我不应该试图引用(俱乐部级)club2.Members,因为它不需要用于创建Person对象。

成员是Club类中的相关数据。由于它是虚拟的,它会执行延迟加载。

在另一种情况下,如果我必须从不同的上下文中检索成员对象(这是一个相关的数据),我应该依靠急切的加载(在为您提供Club对象的地方)。

也请参阅以下内容:

  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

+0

@AmiramKorach你对这种方法有什么看法? – Lijo 2012-07-26 06:34:40

+1

坚持Amiram的建议。这仅适用于您将实体重新附加到新的上下文。我认为在你的情况下,你想使用Include来进行急切的加载。每次你想访问导航属性时打开新的上下文不是一个好主意。请记住,因为您将导航属性标记为虚拟,因此EF将返回动态代理,该代理在处理上下文时不起作用。在关闭上下文之前返回所需的所有数据将解决问题。 – JaySilk84 2012-07-26 07:29:20

+0

我觉得这很危险。正如我上面所说的,我不认为有必要在CheckValues中打开一个新的上下文。此外,我不会尝试将实体附加到多个上下文。我不确定你不会为此得到例外。 – 2012-07-26 07:38:35

7

,因为你要丢弃的的DbContext执行查询后,您会收到此错误。如果你想使用“成员”中的数据,然后加载与查询: http://blogs.msdn.com/b/adonet/archive/2011/01/31/using-dbcontext-in-ef-feature-ctp5-part-6-loading-related-entities.aspx

如果你不需要延迟加载,这意味着只有你在查询加载的数据加载(这将消除异常),设置LazyLoadingEnabled = false。看看这里: Disable lazy loading by default in Entity Framework 4

+0

我不需要在俱乐部实体的会员数据(以我称之为的点)。即使在那个时候,也没有会员加入俱乐部。我需要的是摆脱例外;不加载数据。如何避免异常? – Lijo 2012-07-25 14:39:41

+0

刚刚编辑我的答案 – 2012-07-26 03:23:55

相关问题