C# 如何正确解决有关DataContext、IDisposable和Controls.Clear()的这种情况
我正在Windows窗体应用程序上使用Entity Framework 4作为我的ORM 我有一系列用户控件,它们的功能就像MainForm.cs中的窗体或区域一样。我这样做的原因是为了方便地交换表单“内容”块中要显示的内容 因此,当我单击按钮(在左侧)时,I.Clear()清除“内容”块中当前存在的任何控件,并添加select表单 以下是相关代码:C# 如何正确解决有关DataContext、IDisposable和Controls.Clear()的这种情况,c#,winforms,entity-framework-4,datacontext,idisposable,C#,Winforms,Entity Framework 4,Datacontext,Idisposable,我正在Windows窗体应用程序上使用Entity Framework 4作为我的ORM 我有一系列用户控件,它们的功能就像MainForm.cs中的窗体或区域一样。我这样做的原因是为了方便地交换表单“内容”块中要显示的内容 因此,当我单击按钮(在左侧)时,I.Clear()清除“内容”块中当前存在的任何控件,并添加select表单 以下是相关代码: private void navigationBar_Click(object sender, EventArgs e) {
private void navigationBar_Click(object sender, EventArgs e)
{
//panelHolder is a regular Winforms Panel control.
panelHolder.Controls.Clear();
switch (sender.ToString())
{
case "alumnos":
var studentForm = new Students.StudentListerForm();
panelHolder.Controls.Add(studentForm);
break;
case "personal":
var personalForm = new Personal.PersonalListerForm();
panelHolder.Controls.Add(personalForm);
break;
case "atendencia":
var atendenciaForm = new Attendance.StudentAttendanceForm();
atendenciaForm.ShowDialog();
break;
case "cursos":
var gradeForm = new Grades.GradeListerForm();
panelHolder.Controls.Add(gradeForm);
break;
case "centralizador":
MessageBox.Show("est");
break;
case "libretas":
Scores.StudentScores scores = new Scores.StudentScores();
panelHolder.Controls.Add(scores);
break;
}
}
现在,每个UserControl都管理自己的数据上下文的创建和使用。在每个控件中,我都有代码,例如:
using (GradeRepository repo = new GradeRepository())
{
cmbGrade.DataSource = repo.FindAllGrades();
}
下面是GradeRepository的代码:
public class GradeRepository : IDisposable
{
ColegioDBV2Entities db = new ColegioDBV2Entities();
public IQueryable<Grade> FindAllGrades()
{
return db.Grades;
}
public void Add(Grade grade)
{
db.AddToGrades(grade);
}
public void SaveChanges()
{
db.SaveChanges();
}
public void Dispose()
{
db.Dispose();
}
}
有人能提出解决这个问题的正确方法吗?.Clear()方法是否会成功地处理任何对象,因此不需要使用using
语句
感谢您抽出时间。您可能返回了一个支持延迟执行的
IQueryable
。这意味着,您将返回IQueryable
,然后处理附加的DataContext
。当执行IQuerable
时(稍后的某个时间),它会尝试访问现在已释放的DataContext
。您可能可以这样做:
cmbGrade.DataSource = repo.FindAllGrades().ToList();
您可能会返回一个支持延迟执行的
IQueryable
。这意味着,您将返回IQueryable
,然后处理附加的DataContext
。当执行IQuerable
时(稍后的某个时间),它会尝试访问现在已释放的DataContext
。您可能可以这样做:
cmbGrade.DataSource = repo.FindAllGrades().ToList();
将DataContext作为窗体范围上的属性,并在窗体被销毁时让它销毁。将DataContext作为窗体范围上的属性,并在窗体被销毁时让它销毁。这听起来可能是问题的根源,但我怀疑它是否是。异常在.Clear()行上被清楚地触发,所以我相对确定这是因为它试图处理一个已经被处理的对象。这有意义吗?谢谢你的帮助。:)这可能正是问题所在。如果
Clear
方法在任何附加控件上内部调用Dispose
,则Dispose
将再次被触发。如果控件将Dispose
调用链接到DataSource
属性。好的,那么您建议我如何处理此问题?我在问题中发布的临时解决方案感觉不对劲,但我可能想得太多了。可能Clear方法正在对UserControl中的所有内容调用dispose。你能确认吗?如果你在DataContext
的范围内调用ToList
,查询会立即执行并返回,这意味着当你稍后调用Clear
时,它没有什么可以处理的。这听起来可能是问题的根源,但我怀疑它是否是。异常在.Clear()行上被清楚地触发,所以我相对确定这是因为它试图处理一个已经被处理的对象。这有意义吗?谢谢你的帮助。:)这可能正是问题所在。如果Clear
方法在任何附加控件上内部调用Dispose
,则Dispose
将再次被触发。如果控件将Dispose
调用链接到DataSource
属性。好的,那么您建议我如何处理此问题?我在问题中发布的临时解决方案感觉不对劲,但我可能想得太多了。可能Clear方法正在对UserControl中的所有内容调用dispose。你能确认吗?我会照我说的做,如果你在你的DataContext
范围内调用ToList
,查询会被执行并立即返回,这意味着当你稍后调用Clear
时,它没有什么要处理的。