Warning: file_get_contents(/data/phpspider/zhask/data//catemap/5/reporting-services/3.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# 如何使用可选参数从非常大的数据集中检索数据?_C#_Sql - Fatal编程技术网

C# 如何使用可选参数从非常大的数据集中检索数据?

C# 如何使用可选参数从非常大的数据集中检索数据?,c#,sql,C#,Sql,我有一个应用程序可以检索用户请求的数据。除类型之外的所有参数都是可选的。如果未指定参数,则检索所有项。如果指定,则仅检索与该参数对应的项。例如,这里我按发布年份检索产品(-1是默认值,如果用户没有指定): 这种方法在某些年份效果很好。例如,如果我搜索2001,我会得到所有需要的条目。但是由于products的大小有限,只能检索1500个条目,因此以后的年份根本无法检索,也不在products列表中,即使数据库中有数据,该年份也没有数据 如何解决这个问题?在LINQ上延迟执行的好处之一是,它可以帮

我有一个应用程序可以检索用户请求的数据。除
类型
之外的所有参数都是可选的。如果未指定参数,则检索所有项。如果指定,则仅检索与该参数对应的项。例如,这里我按发布年份检索产品(-1是默认值,如果用户没有指定):

这种方法在某些年份效果很好。例如,如果我搜索2001,我会得到所有需要的条目。但是由于
products
的大小有限,只能检索1500个条目,因此以后的年份根本无法检索,也不在
products
列表中,即使数据库中有数据,该年份也没有数据


如何解决这个问题?

在LINQ上延迟执行的好处之一是,它可以帮助具有变量筛选规则的代码变得更加整洁和可读。如果您不确定延迟执行是什么,简而言之,它是一种仅在请求结果时而不是在生成构成查询的语句时运行LINQ查询的机制

本质上,这意味着我们可以编写如下代码:

//always adults 
var p = person.Where(x => x.Age > 18);

//we maybe filter on these
if(email != null)
  p = p.Where(x => x.Email == email);
if(socialSN != null)
  p = p.Where(x => x.SSN == socialSN);

var r = p.ToList();  //the query is only actually run now
的多次调用,其中
是累积的;他们将在概念上构建where子句,但在调用ToList之前不会执行查询。此时,如果数据库正在使用中,db将看到查询及其所有Where子句,并可以利用索引和统计信息

如果我们在每个Where之后使用ToList,那么第一个Where将命中数据库,它的整个数据集将下载到客户端应用程序,运行时将开始将可枚举数据转换为列表(大量复制和内存分配)。随后的Where将过滤客户端应用程序中的列表,对其进行枚举,然后再次将其转换为列表-最大的问题是它在客户端应用程序的内存中作为一些未编制索引的循环进行,微软投入数百万美元的研发工作,让他们的SQL Server查询优化器能够非常快速地提取大量数据,这些都被浪费掉了:)


再考虑一下,我的示例集合中的第一个子句-Age>18可能是巨大的;例如,100万年龄分布在12岁以上的人——该谓词的大量数据是正确的。电子邮件或SSN将是一个小得多的数据集,可能是索引等。这是一个人为的例子,当然,但希望能很好地说明关于性能的观点;通过过早地列出,我们最终下载了太多的数据

也许不总是列出是一种优化,因为这将触发查询运行。如果您只是在何处,那么EF将构建查询字符串,而不会命中db,这意味着当最终调用ToList时,db可以执行更多的FilteringHanks,这很有效!我再给你加一点背景资料作为回答
//always adults 
var p = person.Where(x => x.Age > 18);

//we maybe filter on these
if(email != null)
  p = p.Where(x => x.Email == email);
if(socialSN != null)
  p = p.Where(x => x.SSN == socialSN);

var r = p.ToList();  //the query is only actually run now