我需要在客户数据库上编写一个动态查询,以获取客户的几个字段。
以下是代码
[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条记录。
答案 0 :(得分:3)
好的,答案是
在最后到达“ToList”之前,不会执行查询 你的方法
来自@GeorgPatscheider分享的MSDN link
执行查询表达式的时间可能会有所不同。 LINQ查询 总是在迭代查询变量时执行,而不是在何时执行 查询变量已创建。这称为延迟执行
延迟执行可以组合多个查询或查询 待延长扩展查询时,会将其修改为包含 新的操作,最终的执行将反映出来 变化。
它还写道,如果查询包含Average
,Count
,First
或Max
中的任何一个,它将执行立即执行。
感谢。
答案 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是对此的一个很好的参考。