Выражение Linq Select медленное при получении COUNT - PullRequest
6 голосов
/ 17 июня 2011

Я пытаюсь получить общее количество записей из приведенного ниже метода, используя EntityFramework и Linq.Медленно возвращать счет.

public static int totalTracking(int id)
{
   using (var ctx = new GPEntities())
   {
      var tr = ctx.Tracking
                   .Where(c => c.clientID == Config.ClientID)
                   .Where(c => c.custID == id)
                   .Where(c => c.oOrderNum.HasValue)
                  .ToList();
      return tr.Count();
   }        
}

Ответы [ 3 ]

10 голосов
/ 17 июня 2011

Вы можете значительно упростить запрос:

using (var ctx = new GPEntities())
{
    return ctx.Tracking
        .Where(c => c.clientID == Config.ClientID)
        .Where(c => c.custID == id)
        .Where(c => c.oOrderNum.HasValue)
        .Count();
}

При вызове ToList это вызовет материализацию, поэтому запрос будет отправлен в базу данных, и будут извлечены все столбцы.Фактический счетчик произойдет на клиенте.

Если вы просто наберете Count, без ToList он выдаст запрос при вызове Count, и сервер вернет только один номер вместо таблицы.

Это не так критично для производительности, но я думаю, что код выглядел бы немного неплохо без стольких Where:

using (var ctx = new GPEntities())
{
    return ctx.Tracking
        .Where(c => 
            c.clientID == Config.ClientID &&
            c.custID == id &&
            c.oOrderNum.HasValue)
        .Count();
}

или даже

using (var ctx = new GPEntities())
{
    return ctx.Tracking
        .Count(c => 
            c.clientID == Config.ClientID &&
            c.custID == id &&
            c.oOrderNum.HasValue);
}
3 голосов
/ 17 июня 2011

Вы можете существенно упростить вещи и просто использовать Метод расширения счета

Вы пробовали:

public static int totalTracking(int id)
{
    using (var ctx = new GPEntities())
    {
        return ctx.Tracking.Count(
                  c => c.clientID == Config.ClientID &&
                       c.custID == id &&
                       c.oOrderNum.HasValue);
    }        
}
2 голосов
/ 17 июня 2011

Удалить звонок .ToList().Он заставляет запрос перенаправить все результаты на клиент.

Удалив это и просто вызвав .Count () непосредственно для результатов tr (без ToList()), Count() становится частьюсамого запроса и выполняется удаленно, что значительно упростит это:

public static int totalTracking(int id)
{
    using (var ctx = new GPEntities())
    {
        var tr = ctx.Tracking
            .Where(c => c.clientID == Config.ClientID)
            .Where(c => c.custID == id)
            .Where(c => c.oOrderNum.HasValue);

        // This can be added above, or left here - the end result is the same
        return tr.Count();
    }        
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...