Есть следующий метод:
public static bool IfStudentHasProblems(CollegeContext db, Student student, ControlPoint cp)
{
foreach (var mark in db.Marks.Where(m => m.Student.StudentId == student.StudentId))
{
if (mark.ControlPoint == cp && mark.Value < 4)
return true;
}
return false;
}
При обращении к db.Marks выбрасывает исключкение выше.
Код вызывающий метод:
private void groupComboBox_SelectedIndexChanged(object sender, EventArgs e)
{
if (groupComboBox.SelectedIndex != 0)
{
int num = Convert.ToInt32(groupComboBox.SelectedItem);
selectedGroup = db.Groups.FirstOrDefault(g => g.Number == num);
studentListView.Items.Clear();
foreach (var student in db.Students.Where(s => s.Group.Number == selectedGroup.Number).OrderBy(s => s.LastName).ThenBy(s => s.FirstName))
if (CalculationUtils.IfStudentHasProblems(db, student, selectedCP))
studentListView.Items.Add(student.LastName + " " + student.FirstName).BackColor = Color.Goldenrod;
else
studentListView.Items.Add(student.LastName + " " + student.FirstName);
if (selectedCP != null)
WriteStatistics();
}
else
{
selectedGroup = null;
studentListView.Items.Clear();
}
}
Так же есть похожий метод, который выполняется без ошибок:
public static int CountStudentsWithBadMarks(CollegeContext db, Group group, ControlPoint cp)
{
int c = 0;
foreach (var m in db.Marks.Where(m => m.Student.Group.Number == group.Number))
if (m.ControlPoint.Date == cp.Date)
if (m.Value < 4)
c++;
return c;
}
Помогите пожалуйста разобраться, где ошибка и как исправить.
Ответ
Такое происходит потому что вы пытаетесь делать один запрос к БД в то время пока идет перебор результатов другого запроса к БД.
Если посмотреть какие запросы к БД вы делаете, то получится как-то вот так:
foreach (var student in db.Students.Where(...))
{
foreach (var mark in db.Marks.Where(m => m.Student.StudentId == student.StudentId))
{
// ...
}
}
Исправить проблему можно несколькими способами:
(не работает для MySQL) разрешить соединению иметь несколько открытых дата ридеров - добавить MultipleActiveResultSets=true в строку подключения к БД;
материализовать внешний запрос
foreach (var student in db.Students.Where(...).ToList())
{
foreach (var mark in db.Marks.Where(m => m.Student.StudentId == student.StudentId))
{
// ...
}
}
использовать навигационные свойства вместо дополнительных запросов совместно с eager loading:
foreach (var student in db.Students.Where(...).Include(s => s.Marks))
{
foreach (var mark in student.Marks)
{
// ...
}
}
Комментариев нет:
Отправить комментарий