• 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]

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

  • 相关阅读:
    实现PHP Thread基类
    完美实现PHP多线程
    Centos操作记录(一)
    Centos Minimal7 安装问题
    Server Git开发流程
    APP Git协作流程
    git学习笔记
    CentOS安装Nginx
    C++学习笔记(一)
    sql进阶:分组查询、子查询、连接查询
  • 原文地址:https://www.cnblogs.com/wphl-27/p/10979413.html
Copyright © 2020-2023  润新知