C# 中的 IEnumerable 与 IQueryable

作者:微信公众号:【架构师老卢】
8-10 18:33
4

概述:在 C# 中使用集合时,您经常会遇到的两个基本接口是 和 。两者在使用 C# 编程进行数据操作中都起着至关重要的作用,了解它们的差异和适当的用例可以显著提高代码的性能和可维护性。在这篇博文中,我将讨论 WHAT 和 ARE、它们的主要区别以及何时使用它们。什么是 IEnumerable?IEnumerable 是命名空间中的一个接口,允许您循环访问指定类型的集合。它是可以枚举的所有非泛型集合的基接口。此处发生延迟执行,这意味着在迭代数据时执行查询。这适用于内存中集合,例如数组、列表和其他集合类型。这将提供一个单一方法,该方法返回一个遍历集合的“IEnumerator”。// Assuming

在 C# 中使用集合时,您经常会遇到的两个基本接口是 和 。两者在使用 C# 编程进行数据操作中都起着至关重要的作用,了解它们的差异和适当的用例可以显著提高代码的性能和可维护性。在这篇博文中,我将讨论 WHAT 和 ARE、它们的主要区别以及何时使用它们。

什么是 IEnumerable?

IEnumerable 是命名空间中的一个接口,允许您循环访问指定类型的集合。它是可以枚举的所有非泛型集合的基接口。

此处发生延迟执行,这意味着在迭代数据时执行查询。这适用于内存中集合,例如数组、列表和其他集合类型。这将提供一个单一方法,该方法返回一个遍历集合的“IEnumerator”。

// Assuming this is a collection retrieved from a database
List<int> numbers = new List<int> { 1, 2, 3, 4, 5 };

// IEnumerable query
IEnumerable<int> query = numbers.Where(n => n > 2);

// In-memory filtering
foreach (int number in query)
{
    Console.WriteLine(number); // Outputs: 3, 4, 5
}

在此示例中,我们创建一个整数集合,并使用循环对其进行迭代。通过此过滤过程,该过程发生在服务器内部,这意味着存在内存中过滤。IEnumerable foreach

IEnumerable 的优点

  • 简单易用,适用于内存中集合。
  • 支持使用 LINQ to Objects 进行内存中查询。

IEnumerable 的限制

  • 不支持 IQueryable 等复杂查询功能。
  • 始终处理整个集合,这对于大型数据集可能效率低下。

什么是IQueryable?

IQueryable 是命名空间中的一个接口,允许使用 LINQ 对数据源进行查询。它对于查询数据库和其他内存不足的数据源特别有用。 该接口继承自 。因此,我们可以用它做的任何事情也可以用它来做。但是它们之间存在差异。

这也具有延迟执行,将查询转换为表达式树并在数据源上执行。因此,非常适合查询数据库或远程数据源,并包含用于创建和执行 LINQ 查询的方法。

using (var context = new MyDbContext())  
{  
  // IQueryable query  
  IQueryable<Employee> employees = context.Employees.Where(e => e.Department == "Sales");  
  
  // Database filtering  
  foreach (Employee employee in employees)  
  {  
     Console.WriteLine(employee.Name); // Outputs only employees belongs to sales department   
    
  }  
} 

在此示例中,我们创建一个对象集合,筛选“销售”部门中的对象。当我们循环访问集合时,将执行查询。过滤发生在数据库内部。IQueryable Employee

IQueryable的好处

  • 针对查询远程数据源进行了优化。
  • 支持复杂的查询和组合,将查询转换为 SQL 以便在数据库上执行。
  • 对于大型数据集非常有效,因为它允许服务器端过滤、排序和分页。

IQueryable 的局限性

  • 使用起来比“IEnumerable”更复杂。
  • 性能可能会受到查询和数据源的复杂性的影响。

IEnumerable 和 IQueryable 之间的差异

了解“IEnumerable”和“IQueryable”之间的区别是选择正确的接口以满足优化代码需求的关键。否则,您的应用程序将出现性能问题。

Namespace

  • IEnumerable: System.Collections 命名空间。
  • IQueryable: System.Linq 命名空间。

执行

  • IEnumerable: 在迭代数据时执行查询(延迟执行)。
  • IQueryable: 在枚举查询或转换为类似 collection 方法时执行查询ToList().

执行位置

  • IEnumerable: 在内存中,执行操作。从集合中检索到所有数据后,将在内存中执行操作。
  • IQueryable: 操作通常被翻译成查询语言(例如,用于数据库的 SQL)并在数据源上执行。这允许进行服务器端处理和优化。

查询能力

  • IEnumerable: 支持 LINQ-to-Objects,这意味着它可以在内存中集合上执行 LINQ 查询。
  • IQueryable: 支持 LINQ-to-Entities,这意味着它可以将 LINQ 查询转换为特定于数据库的查询语言(如关系数据库的 SQL)。

性能

  • **IEnumerable:**这最适合内存中集合。
  • IQueryable: 这针对远程数据源进行了优化,并允许执行类似 SQL 的操作。

惰性评估

  • IEnumerable:支持延迟计算。仅当枚举集合时(例如,在 for each 循环中)才执行操作。
  • IQueryable:这也支持延迟评估。在枚举结果之前,不会执行查询,从而实现高效的资源使用。

使用案例

  • IEnumerable: 适用于处理小型到中等大小的内存中集合,其中整个数据集可以放入内存中。通常用于内存中数据、筛选数据和应用转换。
  • IQueryable: 适用于处理大型数据集或应用程序外部的数据源,例如数据库。它是将查询执行卸载到数据源的理想选择,从而实现高效的数据库查询。

在处理已加载到内存中的集合时,选择内存中数据操作(筛选数据、应用转换),以避免不必要的数据库查询,例如查询和筛选内存中的对象列表或使用数组或列表。IEnumerable

当您需要查询数据库或其他远程数据源时,尤其是当您需要通过使用其将 LINQ 查询转换为 SQL 的功能进行高效查询和数据检索时,用于大型数据集或远程数据查询。IQueryable

请注意性能影响,因为在 和 之间切换可能会影响性能,尤其是对于大型数据集或复杂查询。请确保了解执行行为以优化性能。

阅读排行