如何正确解决 DataContext、IDisposable 和 Controls.Clear() 的这种情况
我在 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.
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 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(2)
您可能会返回一个支持延迟执行的
IQueryable
。这意味着,您返回IQueryable
,但随后处置附加的DataContext
。当执行IQuerable
(稍后)时,它会尝试访问现已释放的DataContext
。你也许可以这样做:You are likely returning an
IQueryable<T>
which supports deferred execution. This means, you return theIQueryable<T>
but then dispose the attachedDataContext
. When theIQuerable<T>
is executed (sometime later), it tries to access theDataContext
which has now been disposed. You could probably do this:将 DataContext 作为表单范围的属性,并在表单销毁时让它销毁。
Make the DataContext as a property on the scope of the form and let it destroy when the form is destroyed.