2017-02-01 51 views
0

我收到以下错误,当我想遍历一个列表C#实体框架ObjectContext的实例已经被布置

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

我打开窗体用下面的代码

 private void dataGridView1_CellDoubleClick(object sender, DataGridViewCellEventArgs e) 
     { 
      int id = int.Parse(dataGridView1.Rows[e.RowIndex].Cells[0].Value.ToString()); 
      Aufenthalt a; 
      using (var db = new GastContext()) 
      { 
       a = db.Aufenthalte.First(x => x.AufenthaltID == id); 
      } 

      Aufenthaltsform frm = new Aufenthaltsform(currentGast, a); 
      frm.ShowDialog(); 
     } 

这是我的表单的构造函数和这里我的应用程序抛出上述错误

public Aufenthaltsform(Gast g, Aufenthalt a) 
    { 
     InitializeComponent(); 

     MessageBox.Show(a.Mitreisende.Count.ToString()); 
    } 

这就是Aufenthalt-对象

public class Aufenthalt 
    { 
     public int AufenthaltID { get; set; } 
     public DateTime Anreisedatum { get; set; } 
     public DateTime Abreisedatum { get; set; } 

     public virtual List<Mitreisender> Mitreisende { get; set; } 

     public virtual Gast Gast { get; set; } 

     public Aufenthalt() 
     { 
      Mitreisende = new List<Mitreisender>(); 
     } 
    } 
+0

http://stackoverflow.com/questions/40729137/why-are- foreign-keys-in-ef-code-first-marked-as-virtual/40729675#40729675看看这个有点理论上为什么发生这种情况 –

回答

2

Aufenthalt有两个导航属性 - MitreisendeGast。当您使用延迟加载时,需要不使用DbContext。这就是为什么你有错误,当试图通过using声明配置方面后读取这些属性:

Aufenthalt a; 
using (var db = new GastContext()) 
{ 
    a = db.Aufenthalte.First(x => x.AufenthaltID == id); 
} 

// db is disposed here 
Aufenthaltsform frm = new Aufenthaltsform(currentGast, a); 

您可以:

  • 删除using语句来保持不同情境下活着
  • 使用,而不是延迟加载预先加载
  • 移动表单创建和替换using声明
  • get Mitreisende count并将数字传递给表单,而不是传递根对象并稍后使用导航属性

第一个选项 - DbContext是一个轻量级对象,可以不配置它。

var db = new GastContext(); 
Aufenthalt a = db.Aufenthalte.First(x => x.AufenthaltID == id); 
Aufenthaltsform frm = new Aufenthaltsform(currentGast, a); 

第二个选项 - 不是很好的选择,因为你只需要计算相关的实体。为什么把它们全部加载到内存中但是你可以

Aufenthalt a; 
using (var db = new GastContext()) 
{ 
    a = db.Aufenthalte.Include(x => x.Mitreisende).First(x => x.AufenthaltID == id); 
} 

Aufenthaltsform frm = new Aufenthaltsform(currentGast, a); 

第三个选择是显而易见的

using (var db = new GastContext()) 
{ 
    Aufenthalt a = db.Aufenthalte.First(x => x.AufenthaltID == id); 
    Aufenthaltsform frm = new Aufenthaltsform(currentGast, a); 
    frm.ShowDialog(); 
} 

而且最好选择不流通,以形成不需要的数据。它只需要计数Mitreisende,而不是整个系列。因此,改变你的形式

public Aufenthaltsform(Gast g, int mitreisendeCount) 
{ 
    InitializeComponent(); 
    MessageBox.Show(mitreisendeCount.ToString()); 
} 

,并呼吁它这样

int mitreisendeCount; 
using (var db = new GastContext()) 
{ 
    mitreisendeCount = db.Aufenthalte.First(x => x.AufenthaltID == id).Mitreisende.Count; 
} 

Aufenthaltsform frm = new Aufenthaltsform(currentGast, mitreisendeCount); 
+0

或使用.Include –

0

您应该确保上下文配置之前执行的查询:

a = db.Aufenthalte.First(x => x.AufenthaltID == id); 
// place this within the disposable context (using) 
int count = a.Mitreisende.Count; 
0

对象a本身在装载后填充,但它有一个导航属性Mitreisende,此时尚未填充(实体框架还记得它尚未完成)。

当您调用a.Mitreisende.Count时,实体框架尝试填充Mitreisende属性,但它不能这样做,因为using语句导致DbContext被丢弃,导致错误。

有多种修复:

1)不要处置的DbContext,只需通过删除using块。 .NET将在稍后的时间自行删除它,在很多情况下这不会造成伤害。

2)自己配置DbContext,但稍后将下一行放入块中,而不是在它之后。

3)确保实体框架尽快加载Mitreisende,而不是将其延迟,使用.Include声明:

a = db.Aufenthalte.Include(x => x.Mitreisende).First(x => x.AufenthaltID == id); 
相关问题