zoukankan      html  css  js  c++  java
  • C#中IQueryable和IEnumerable的区别

    最近的一个面试中,被问到IQueryable 和 IEnumerable的区别, 我自己看了一些文章,总结如下:

    1. 要明白一点,IQueryable接口是继承自IEnumerable的接口的.

    2. IQueryable中有表达式树, 这可以看作是它的一个优势。所以,使用IQueryable操作时,比如对数据的过滤,排序等操作, 这些都会先缓存到表达式树中. 当对数据库操作真正发生时,它才会将表达式树执行来获取数据。

       这也就是说,比如选择top 2两行数据, 它会先在表达式树中缓存这个过滤取top 2的操作。待到操作数据库时,它就会在数据库中筛选top 2数据。 =》 IQueryable 有延时加载机制, 它直接从数据库中筛选数据.

    3. IEnumerable, 它对数据进行操作时,和IQueryable不同,它会事先把所有的数据从数据库获取,放到内存中。然后,在内存中对这些数据进行筛选操作,包括过滤,排序等.  => IEnumerable 在内存中对数据进行筛选

    我们通过举一个用Repository的例子来说明

    public class EmployeeRepository : IEmployeeRepository
    {
        private readonly CompanyContext  _context;
    
        public EmployeeRepository(CompanyContext  context)
        {
             _context = context;
        } 
    
    
        public IEnumerable<Employee> GetIEnumerableEmployees()
        {
            return _context.Employees;
        }
    
       public IQueryable<Employee> GetIQueryableEmployees()
        {
            return _context.Employees;
        }
     
    }

     在Controller中调用

    public class HomeController : Controller
    {
         private readonly IEmployeeRepository _employeeRepository;
         public HomeController(IEmployeeRepository employeeRepository)
         {
               _employeeRepository = employeeRepository;
         }
    
    
         public ActionResult Index()
         {
              //用IEnumerable返回结果测试
              var employees = _employeeRepository.GetIEnumerableEmployees().Take(2);
    
             //用IQueryable返回结果测试
           //  var employees = _employeeRepository.GetIQueryableEmployees().Take(2);
    
          return View(employees);
         }
    
    }

     使用MiniProfiler来检测,会发现两者的区别

    使用IEnumerable检测发现,它在数据库中执行的语句是:

    SELECT
    [Extent].[Id] AS [Id],
    [Extent].[Name] AS [Name],
    [Extent].[Department] AS [Department]
    FROM [dbo].[Employee] AS [Extent]

    可见,它从数据库中取出了所有数据。然后在内存中再筛选.

    使用IQueryable检测发现,它在数据库中执行的语句是:

    SELECT TOP (2)
    [Extent].[Id] AS [Id],
    [Extent].[Name] AS [Name],
    [Extent].[Department] AS [Department]
    FROM [dbo].[Employee] AS [Extent]

    可见,它只从数据库中取出了两条数据

  • 相关阅读:
    支持xp风格的manifest
    XPath and TXmlDocument
    TXMLDocument use case (Delphi)
    Delphi中,除了应用程序主窗口会显示在任务栏上,其它窗口默认都不会显示在任务栏.
    Delphi下让窗口不显示在任务栏的另类方法
    拨号、断网、枚举连接名称,判断是否在线、连接方式
    [转]装逼
    这该死的数字化生活
    4根网线水晶头接法(8根只接4根即可通讯)
    关闭Delphi的RTTI
  • 原文地址:https://www.cnblogs.com/wphl-27/p/10979413.html
Copyright © 2011-2022 走看看