【问题标题】:Linq Select Statement slow when getting COUNT获取 COUNT 时,Linq Select 语句很慢
【发布时间】:2011-06-17 00:02:36
【问题描述】:

我正在尝试使用 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();
   }        
}

【问题讨论】:

标签: c# asp.net linq entity-framework linq-to-entities


【解决方案1】:

您可以显着简化查询:

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);
}

【讨论】:

  • 伙计 - 我刚刚看到 .ToList() - 谢谢!您的代码正在运行
  • 我想通过讨论它没有任何见解,但我更喜欢不在 Where-lambdas 中执行复合 AND 表达式。我发现当您只需执行 shift+del 或添加新行时,添加/删除条件变得更容易,并且更容易区分非实数谓词。
【解决方案2】:

您可以大大简化事情,只需使用Count Extension method

你试过了吗:

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);
    }        
}

【讨论】:

  • 顺便说一句 - 错误的扩展方法链接 - 尝试 msdn.microsoft.com/en-us/library/bb534807.aspx 代替...
  • @Reed Copsey thxs,如果微软停止弄乱他们的文档,那么回答 StackOverflow 问题会变得容易得多:)
  • @Nik:没问题 - 你拥有的是 IEnumerable,而不是 IQueryable ;)
【解决方案3】:

删除呼叫.ToList()。它强制查询将整个结果拉到客户端。

通过删除它,直接在 tr 的结果上调用 .Count()(没有 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();
    }        
}

【讨论】:

    猜你喜欢
    • 2018-06-10
    • 1970-01-01
    • 2015-12-14
    • 2023-03-15
    • 2012-10-13
    • 2016-05-21
    • 1970-01-01
    • 2020-05-18
    • 1970-01-01
    相关资源
    最近更新 更多