首页 > C# > 返回与返回有什么区别,什么时候应该优先于另一个?IQueryableIEnumerable

返回与返回有什么区别,什么时候应该优先于另一个?IQueryableIEnumerable

上一篇 下一篇

返回与返回有什么区别,什么时候应该优先于另一个?IQueryable<T>IEnumerable<T>

IQueryable<Customer> custs = from c in db.Customers
where c.City == "<City>"
select c;

IEnumerable<Customer> custs = from c in db.Customers
where c.City == "<City>"
select c;

两者都会被推迟执行,什么时候应该优先于另一个?

分割线

网友回答:

顶部答案很好,但它没有提到解释两个接口“如何”不同的表达式树。基本上,有两组相同的 LINQ 扩展。、 等都有两个版本:一个接受函数,另一个接受表达式。Where()Sum()Count()FirstOrDefault()

  • 版本签名为:IEnumerableWhere(Func<Customer, bool> predicate)
  • 版本签名为:IQueryableWhere(Expression<Func<Customer, bool>> predicate)

您可能一直在使用这两种语法而没有意识到,因为两者都使用相同的语法调用:

例如 适用于两者和Where(x => x.City == "<City>")IEnumerableIQueryable

  • 在集合上使用时,编译器将编译的函数传递给Where()IEnumerableWhere()
  • 在集合上使用时,编译器会将表达式树传递给 。表达式树类似于反射系统,但用于代码。编译器将代码转换为数据结构,以易于理解的格式描述代码的功能。Where()IQueryableWhere()

为什么要为这个表达式树的事情而烦恼?我只想让 Where() 过滤我的数据。
主要原因是 EF 和 Linq2SQL ORM 都可以将表达式树直接转换为 SQL,其中代码的执行速度要快得多。

哦,这听起来像是免费的性能提升,在这种情况下,我应该到处使用 AsQueryable() 吗?
否,仅当基础数据提供程序可以对其进行操作时才有用。将常规之类的东西转换为不会给您带来任何好处。
IQueryableListIQueryable

分割线

网友回答:

是的,两者都会给你延迟执行。

区别在于允许 LINQ-to-SQL(实际上是 LINQ to-anything)工作的接口。因此,如果进一步细化查询,如果可能,该查询将在数据库中执行。IQueryable<T>IQueryable<T>

对于这种情况,它将是 LINQ-to-object,这意味着与原始查询匹配的所有对象都必须从数据库加载到内存中。IEnumerable<T>

在代码中:

IQueryable<Customer> custs = ...;
// Later on...
var goldCustomers = custs.Where(c => c.IsGold);

该代码将执行 SQL 以仅选择黄金客户。另一方面,以下代码将在数据库中执行原始查询,然后过滤掉内存中的非黄金客户:

IEnumerable<Customer> custs = ...;
// Later on...
var goldCustomers = custs.Where(c => c.IsGold);

这是一个非常重要的区别,在许多情况下,处理可以避免从数据库中返回太多行。另一个主要的例子是分页:如果使用 和 on ,则只会获得请求的行数;在 上执行此操作将导致所有行都加载到内存中。IQueryable<T>TakeSkipIQueryableIEnumerable<T>

分割线

网友回答:

是的,两者都使用延迟执行。让我们使用 SQL Server 探查器来说明其中的区别。

当我们运行以下代码时:

MarketDevEntities db = new MarketDevEntities();

IEnumerable<WebLog> first = db.WebLogs;
var second = first.Where(c => c.DurationSeconds > 10);
var third = second.Where(c => c.WebLogID > 100);
var result = third.Where(c => c.EmailAddress.Length > 11);

Console.Write(result.First().UserName);

在 SQL Server 探查器中,我们找到一个等于以下内容的命令:

"SELECT * FROM [dbo].[WebLog]"

针对包含 90 万条记录的 WebLog 表运行该代码块大约需要 1 秒。

因此,所有表记录都作为对象加载到内存中,然后与每个 .Where() 它将是内存中针对这些对象的另一个过滤器。

当我们使用而不是在上面的例子中(第二行)时:IQueryableIEnumerable

在 SQL Server 探查器中,我们找到一个等于以下内容的命令:

"SELECT TOP 1 * FROM [dbo].[WebLog] WHERE [DurationSeconds] > 10 AND [WebLogID] > 100 AND LEN([EmailAddress]) > 11"

使用 运行此代码块大约需要 4 秒钟。IQueryable

IQueryable 有一个名为的属性,它存储了一个树表达式,当我们在示例中使用 (称为延迟执行)时,该表达式开始创建,最后此表达式将转换为 SQL 查询以在数据库引擎上运行。Expressionresult

模板简介:该模板名称为【返回与返回有什么区别,什么时候应该优先于另一个?IQueryableIEnumerable】,大小是暂无信息,文档格式为.编程语言,推荐使用Sublime/Dreamweaver/HBuilder打开,作品中的图片,文字等数据均可修改,图片请在作品中选中图片替换即可,文字修改直接点击文字修改即可,您也可以新增或修改作品中的内容,该模板来自用户分享,如有侵权行为请联系网站客服处理。欢迎来懒人模板【C#】栏目查找您需要的精美模板。

相关搜索
  • 下载密码 lanrenmb
  • 下载次数 251次
  • 使用软件 Sublime/Dreamweaver/HBuilder
  • 文件格式 编程语言
  • 文件大小 暂无信息
  • 上传时间 02-18
  • 作者 网友投稿
  • 肖像权 人物画像及字体仅供参考
栏目分类 更多 >
热门推荐 更多 >
微信文章 微信公众平台 微信素材 企业网站 单页式简历模板 自适应 微信图片 微信模板 响应式 html5
您可能会喜欢的其他模板