Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/magento/5.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 获取计数时Linq Select语句变慢_C#_Asp.net_Linq_Entity Framework_Linq To Entities - Fatal编程技术网

C# 获取计数时Linq Select语句变慢

C# 获取计数时Linq Select语句变慢,c#,asp.net,linq,entity-framework,linq-to-entities,C#,Asp.net,Linq,Entity Framework,Linq To Entities,我正在尝试使用EntityFramework和Linq从下面的方法中获取总记录数。返回计数很慢 public static int totalTracking(int id) { using (var ctx = new GPEntities()) { var tr = ctx.Tracking .Where(c => c.clientID == Config.ClientID) .Wher

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

您可以显著简化查询:

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()
。它强制查询将整个结果拉到客户端

通过删除此项,并直接对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();
    }        
}

你可以大大简化事情,只需使用

您是否尝试过:

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

这里有一种加速的方法,将.Where查询合并成一个。我刚刚读了一篇关于这个的文章。老兄,我刚刚看到了。托利斯特()-谢谢!您的代码正在运行,我想讨论它并没有什么见解,但我不喜欢在Where lambdas中使用复合和表达式。我发现,当你只需执行shift+del或添加新行时,添加/删除条件变得更容易,并且更容易区分非实谓词。顺便说一句-错误的扩展方法链接-改为尝试…@Reed Copsey thxs,如果微软不再乱动他们的文档,那么回答StackOverflow问题就容易多了:)@Nik:没问题-你的问题是IEnumerable,而不是IQueryable;)