IQueryable的表现

时间:2016-07-11 11:31:57

标签: c# entity-framework

我需要在客户数据库上编写一个动态查询,以获取客户的几个字段。

以下是代码

[Route("api/getBasicCustList/{argType}/{argValue}")]
        [HttpGet]
        [Authorize]

        public dynamic getCustomerDataUsername(String argType, String argValue)
        {
            IQueryable<CustomerDTO> query =
               (from recordset in db.Customers
                     select new CustomerDTO
                               {
                                   companyId = recordset.Company.Id,
                                   contactNum = recordset.ContactNum,
                                   username = recordset.UserName,
                                   emailAddress = recordset.Email,
                                   fullName = recordset.FullName,
                                   accountNumber = recordset.RCustId
                               }
                );

            switch (argType)
            {
                case "username" :
                    query = query.Where(c => c.username.StartsWith(argValue));
                    break;
                case "contactnum":
                    long mobNum = Int64.Parse(argValue);
                    query = query.Where(c => c.contactNum == mobNum);
                    break;
                case "fullname":
                    query = query.Where(c => c.fullName.Contains(argValue));
                    break;
            }

            return new { data = query.ToList() };
        }

这很好用,正在解决我的目的。

我的问题是,当我编写query的第一部分以获取所有客户记录时,稍后将动态应用where条件将结果带入内存或生成完整查询并在db中一次性执行?

由于我现在只有500条记录,我无法找到任何性能滞后,但是当我将其投入生产时,我将处理至少200,000到300,000条记录。

2 个答案:

答案 0 :(得分:3)

好的,答案是

  

在最后到达“ToList”之前,不会执行查询   你的方法

来自@GeorgPatscheider分享的MSDN link

  

执行查询表达式的时间可能会有所不同。 LINQ查询   总是在迭代查询变量时执行,而不是在何时执行   查询变量已创建。这称为延迟执行

     

延迟执行可以组合多个查询或查询   待延长扩展查询时,会将其修改为包含   新的操作,最终的执行将反映出来   变化。

它还写道,如果查询包含AverageCountFirstMax中的任何一个,它将执行立即执行

感谢。

答案 1 :(得分:0)

提高大表查询性能的最大因素是在服务器(数据库)端进行过滤。在Entity Framework 6.x和更早版本中,如果EF无法将整个查询转换为SQL,则查询将无法编译。在EF Core中,情况不再如此。而是将尽可能多的查询转换为SQL。其余的将在客户端进行评估。

所有三个过滤lambda表达式都可以转换为SQL。但是,如果您要编写无法转换的谓词,那么在EF Core上,您的性能将会受到影响。尽管查询的评估仍会推迟到调用0之前,但是Customer表中的所有记录都将发送到客户端进行过滤。您的日志将contain a warning,但是很容易丢失。

Jon Smiths的文章Entity Framework Core: Client vs. Server evaluation是对此的一个很好的参考。