Как я могу ускорить мой запрос LINQ без использования таблицы в два раза? - PullRequest
0 голосов
/ 01 мая 2018

Так что я использую таблицу в своем запросе дважды, и я не знаю другого способа использовать ее только один раз. Вот мой запрос:

var result = (from t1 in (from t1 in db.Students.Where(en => en.Progress == MyEnum.Accepted).GroupBy(en => en.Class).AsEnumerable()
                          join t2 in dbOther.Classes on t1.Key equals t2.Class 
                          select t2)
              join t3 in (db.Students).AsEnumerable() on t1.Class equals t3.Class into t4
              select new
                          {
                              ClassNum = t1.Class,
                              StartDate = t1.StartDate,
                              Weeks = t1.Weeks,
                              Accepted = t4.Where(e => e.Progress == MyEnum.Accepted).Count(),
                              NotAccepted = t4.Where(e => e.Progress < MyEnum.Accepted).Count()
                          }).ToList();

Мне нужно получать только те классы, в которых учащиеся находятся в принятом состоянии. Затем я хочу получить классы и подсчитать весь список, даже студентов, которые не принимаются. Есть лучший способ сделать это? Кажется, что чтение из одной и той же таблицы дважды - не самый быстрый способ сделать это.

Спасибо за помощь.

Ответы [ 3 ]

0 голосов
/ 01 мая 2018

Вместо ИСПОЛЬЗОВАНИЯ ". Enumerable ()" над объектом студенческого БД, используйте Querable. Это создаст выражение, которое будет оцениваться на уровне базы данных, а не сначала извлекать всю таблицу учеников, а затем делать сравнение.

Проверьте это для подробностей Возвращение IEnumerable против IQueryable

Просто попробуйте установить профилировщик и увидеть сгенерированные запросы как для Enumerable, так и для Queryable. Здесь будет показано различие.

Инфраструктура сущностей проще всего демонстрируется с различиями в исполнении с помощью обоих этих методов. Также самый простой ORM для поддержки этих функций.

0 голосов
/ 01 мая 2018

Сначала получите информацию о зачислении студентов из таблицы db.Students:

var stats = db.Students
    .GroupBy(en => en.Class)
    .Select(g => new {
        Class = g.Key
    ,   Accepted = g.Count(en => en.Progress == MyEnum.Accepted)
    ,   NotAccepted = g.Count(en => en.Progress < MyEnum.Accepted)
    })
    .Where(g => g.Accepted != 0)
    .ToList();

Далее, извлекаем классы из другой базы данных:

var classIds = stats.Select(en => en.Class).ToList();
var classes = dbOther.Classes.Where(c => classIds.Contains(c.Class)).ToList();

Наконец, объедините два результата:

var result = (from s in stats
    join c in classes on c.ClassId = s.ClassId
    select new {
        ClassNum = c.Class
    ,   c.StartDate
    ,   c.Weeks
    ,   s.Accepted
    ,   s.NotAccepted
    }).ToList();
0 голосов
/ 01 мая 2018

Если вы действительно не упрощаете запрос здесь, вам не нужно нажимать dbOther, чтобы узнать, в каких классах есть учащиеся в состоянии Приняты. Эта информация в db.

var studentCountPerClass = (from s in db.Students
                            group s by s.Class into studentsByClass    
                            where studentsByClass.Any(x => x.Progress == MyEnum.Accepted)
                            select new
                            {
                                ClassNum = studentsByClass.Key,
                                Accepted = studentsByClass.Count(s => s.Progress == MyEnum.Accepted),
                                NotAccepted = studentsByClass.Count(s => s.Progress < MyEnum.Accepted),
                            })
                            .ToList();

var classCodes = studentCountPerClass.Select(x => x.ClassNum).ToList(); 
var classData = (from c in dbOther.Classes
                    where classCodes.Contains(c.Class)
                    select new {
                        c.Class,
                        // Any other data you want about the class
                    })
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...