Страницы

Поиск по вопросам

среда, 5 февраля 2020 г.

Как должен выглядеть этот же запрос в linq

#c_sharp #linq


StudentsOfFaculti - это студенты. 
contextDB.tableBalli - это баллы студентов по разным дисциплинам.Таблицы связаны
по ID_Studenta. Я нахожу студентов у которых по всем дисциплинам больше 40 баллов.
Если у студента хотя бы по одной дисциплине меньше 40 то пропускаю этого студента.
Не знаю как написать linq запрос, чтобы был тот же результат.

int AbsolutnayaUspevaemost = 0;

foreach (var ksf in StudentsOfFaculti)
{
    foreach (var b in contextDB.tableBalli)
    {
        if (ksf.ID == b.ID_Studenta && b.Itog >= 41)
        {

        }
        else
        {
            AbsolutnayaUspevaemost--;
            break;
        }
    }
    AbsolutnayaUspevaemost++;
}

    


Ответы

Ответ 1



Пока вот сообразил такое решение - выдает количество неуспевающих: using System; using System.Collections.Generic; using System.Linq; class Program { static void Main() { List students = new List { new Student { ID = 0 }, new Student { ID = 1 }, new Student { ID = 2 }, new Student { ID = 3 }, new Student { ID = 4 }, new Student { ID = 5 }, new Student { ID = 6 }, new Student { ID = 7 }, new Student { ID = 8 }, new Student { ID = 9 } }; List marks = new List { new Mark { ID_Studenta = 0, Itog = 41 }, new Mark { ID_Studenta = 0, Itog = 48 }, new Mark { ID_Studenta = 0, Itog = 43 }, new Mark { ID_Studenta = 1, Itog = 40 }, new Mark { ID_Studenta = 1, Itog = 41 }, new Mark { ID_Studenta = 1, Itog = 28 }, new Mark { ID_Studenta = 2, Itog = 50 }, new Mark { ID_Studenta = 2, Itog = 55 }, new Mark { ID_Studenta = 2, Itog = 59 }, new Mark { ID_Studenta = 3, Itog = 30 }, new Mark { ID_Studenta = 3, Itog = 29 }, new Mark { ID_Studenta = 3, Itog = 36 }, new Mark { ID_Studenta = 4, Itog = 48 }, new Mark { ID_Studenta = 4, Itog = 46 }, new Mark { ID_Studenta = 4, Itog = 42 }, new Mark { ID_Studenta = 5, Itog = 41 }, new Mark { ID_Studenta = 5, Itog = 40 }, new Mark { ID_Studenta = 5, Itog = 43 }, new Mark { ID_Studenta = 6, Itog = 39 }, new Mark { ID_Studenta = 6, Itog = 42 }, new Mark { ID_Studenta = 6, Itog = 46 }, new Mark { ID_Studenta = 7, Itog = 30 }, new Mark { ID_Studenta = 7, Itog = 30 }, new Mark { ID_Studenta = 7, Itog = 50 }, new Mark { ID_Studenta = 8, Itog = 45 }, new Mark { ID_Studenta = 8, Itog = 46 }, new Mark { ID_Studenta = 8, Itog = 49 }, new Mark { ID_Studenta = 9, Itog = 40 }, new Mark { ID_Studenta = 9, Itog = 38 }, new Mark { ID_Studenta = 9, Itog = 48 } }; int c = students.Join(marks, s => s.ID, m => m.ID_Studenta, (s, m) => new { id = s.ID, itog = m.Itog }) .Where(a => a.itog < 41) .GroupBy(a => a.id) .Count(); Console.WriteLine(c); } } class Student { public long ID { get; set; } } class Mark { public long ID_Studenta { get; set; } public int Itog { get; set; } } Более грамотное решение могли бы вам дать специалисты по SQL, возможно стоит добавить сюда такую метку

Ответ 2



Возвращает количество студентов, все оценки которых превышают порог в 40 баллов. class Student { public int Id { get; set; } } class Mark { public int StudentId { get; set; } public int Value { get; set; } } ... var threshold = 40; var count = students .Join(marks, x => x.Id, x => x.StudentId, (x, y) => new { StudentId = x.Id, StudentMark = y.Value }) .GroupBy(x => x.StudentId) .Where(x => !x.Any(y => y.StudentMark <= threshold)) .Count(); Если в таблице с оценками нет оценок каких-то "левых" студентов, отсутствующих в таблице студентов, то от Join можно избавится как от лишней операции: var count = marks .GroupBy(x => x.StudentId) .Where(x => !x.Any(y => y.Value <= threshold)) .Count(); Но, вообще, в логике вашего цикла что-то сильно не так. В тело условия else мы попадаем в двух случаях: оценка некоторого студента является неудовлетворительной; это вообще оценка какого-то другого студента, а не того, которого мы рассматриваем в настоящий момент. Таким образом, цикл прерывается и результирующее значение уменьшается каждый раз, когда мы просто натыкаемся не на того студента. Чтобы такого не происходило, цикл можно переписать примерно следующим образом: var result = 0; foreach (var student in students) { result += 1; // foreach (var mark in marks.Where(x => x.StudentId == student.Id)) { if (mark.Value <= threshold) { result -= 1; break; } } }

Ответ 3



Тот же вариант, что и у @Андрей, но в другом стиле: int c = (from mark in marks from student in students where mark.ID_Studenta == student.ID && mark.Itog < 41 group student by student.ID).Count(); Вариант с Join int c = (from mark in marks join student in students on mark.ID_Studenta equals student.ID where mark.Itog < 41 group student by student.ID).Count();

Комментариев нет:

Отправить комментарий