如何正确解决有关DataContext,IDisposable和Controls.Clear()的这种情况

时间:2011-04-11 17:33:04

标签: c# winforms entity-framework-4 datacontext idisposable

我在Windows窗体应用程序中使用Entity Framework 4作为我的ORM。

我有一系列的UserControl,它们就像是我的MainForm.cs中的表单或区域一样。我这样做的原因是为了轻松地交换在表单的“内容”块中显示的内容。

enter image description here

因此,当我点击按钮(左侧)时,我.Clear()当前在'content'块中的任何控件并添加选择表单。

以下是相关代码:

    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();
    }
}

这确保我使用上下文,获取数据,关闭它并处理它。

我的问题在于当我点击我告诉你的其中一个按钮时,panelHolder.Controls.Clear();行触发 ObjectDisposedException

我通过删除相关区域中的using语句暂时解决了这个问题,现在它看起来像是:

GradeRepository repo = new GradeRepository();
cmbGrade.DataSource = repo.FindAllGrades();

有人能建议一个正确的方法来解决这个问题吗? .Clear()方法是否会成功处理任何对象,因此不需要使用using语句?

感谢您的时间。

2 个答案:

答案 0 :(得分:2)

您可能会返回支持延期执行的IQueryable<T>。这意味着,您返回IQueryable<T>,但随后处置附加的DataContext。执行IQuerable<T>时(稍后某个时间),它会尝试访问现已处理的DataContext。你可能会这样做:

cmbGrade.DataSource = repo.FindAllGrades().ToList();

答案 1 :(得分:1)

将DataContext作为表单范围内的属性,并在表单被销毁时销毁。