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

发布于 2024-10-31 22:01:52 字数 2703 浏览 1 评论 0原文

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

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

在此处输入图像描述

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

下面是相关代码:

    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(); 行会触发 ObjectDisposeException

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

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

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

谢谢您的宝贵时间。

I'm using Entity Framework 4 as my ORM on a Windows Forms application.

I have a series of UserControls that function as if they were forms or areas inside my MainForm.cs. The reason I did this was to easily interchange what to display in the 'content' block of the form.

enter image description here

So when I click on the buttons (on the left), I .Clear() whatever controls is currently in the 'content' block and add the select form.

Here's the relevant code:

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

Now, each UserControl manages it's own creation and usage of the data context. Inside of each of these controls I have code for example:

using (GradeRepository repo = new GradeRepository())
{
    cmbGrade.DataSource = repo.FindAllGrades();
}

And here's the code for 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();
    }
}

This ensure I use the context, get data, close it and dispose of it.

My problem lies when I click on one of the buttons I told you about up top, the panelHolder.Controls.Clear(); line fires ObjectDisposedException.

I've temporarily solved this by removing the using statements in the relevant areas, so it now looks like:

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

Can anybody suggest a correct way to tackle this problem? Will the .Clear() method successfully dispose of any objects, so using a using statement is not needed?

Thank you for your time.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

以往的大感动 2024-11-07 22:01:52

您可能会返回一个支持延迟执行的 IQueryable。这意味着,您返回 IQueryable,但随后处置附加的 DataContext。当执行IQuerable(稍后)时,它会尝试访问现已释放的DataContext。你也许可以这样做:

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

You are likely returning an IQueryable<T> which supports deferred execution. This means, you return the IQueryable<T> but then dispose the attached DataContext. When the IQuerable<T> is executed (sometime later), it tries to access the DataContext which has now been disposed. You could probably do this:

cmbGrade.DataSource = repo.FindAllGrades().ToList();
柠檬色的秋千 2024-11-07 22:01:52

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

Make the DataContext as a property on the scope of the form and let it destroy when the form is destroyed.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文