[英]C# Entity Framework ObjectContext instance has been disposed
当我要遍历列表时收到以下错误
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>();
}
}
您的Aufenthalt
具有两个导航属性Mitreisende
和Gast
。 在使用延迟加载时,需要非处置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
语句中移动表单创建和替换 第一种选择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 );
您应该确保在处理上下文之前执行查询:
a = db.Aufenthalte.First(x => x.AufenthaltID == id);
// place this within the disposable context (using)
int count = a.Mitreisende.Count;
对象a
本身加载后填,但它有一个导航属性Mitreisende
尚未在那一刻又充满(和Entity Framework还记得,它没有这样做还)。
当您调用a.Mitreisende.Count
,实体框架会尝试填充Mitreisende属性,但是它不能这样做,因为using
语句导致DbContext被处置,从而导致错误。
有多个修复程序:
1)不要通过删除using
块来处理DbContext。 .NET稍后会自行删除它,这在很多情况下不会受到伤害。
2)自己处理DbContext,但稍后再将其后两行放在该块内,而不是放在其后,再进行处理。
3)使用.Include
语句,确保Entity Framework尽快加载Mitreisende
,而不是延迟加载它:
a = db.Aufenthalte.Include(x => x.Mitreisende).First(x => x.AufenthaltID == id);
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.