Как правильно решить эту ситуацию в отношении DataContext, IDisposable и Controls.Clear () - PullRequest
0 голосов
/ 11 апреля 2011

Я использую Entity Framework 4 в качестве ORM в приложении Windows Forms.

У меня есть серия пользовательских элементов управления, которые функционируют так, как если бы они были формами или областями внутри моего MainForm.cs. Причина, по которой я это сделал, состояла в том, чтобы легко поменять то, что отображать в блоке «содержимого» формы.

enter image description here

Поэтому, когда я нажимаю на кнопки (слева), я .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(); вызывает ObjectDisposedException .

Я временно решил эту проблему, удалив операторы using в соответствующих областях, и теперь он выглядит следующим образом:

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

Кто-нибудь может предложить правильный способ решения этой проблемы? Сможет ли метод .Clear () успешно удалить какие-либо объекты, поэтому использование оператора using не требуется?

Спасибо за ваше время.

Ответы [ 2 ]

2 голосов
/ 11 апреля 2011

Вы, вероятно, возвращаете IQueryable<T>, который поддерживает отложенное выполнение. Это означает, что вы возвращаете IQueryable<T>, но затем утилизируете прикрепленный DataContext. Когда IQuerable<T> выполняется (некоторое время спустя), он пытается получить доступ к DataContext, который был удален. Возможно, вы могли бы сделать это:

cmbGrade.DataSource = repo.FindAllGrades().ToList();
1 голос
/ 11 апреля 2011

Создайте DataContext как свойство в области формы и разрешите ему уничтожаться при уничтожении формы.

...