C#中IQueryable和IEnumerable的區別

最近的一個面試中,被問到IQueryable 和 IEnumerable的區別, 我本身看了一些文章,總結以下:面試

1. 要明白一點,IQueryable接口是繼承自IEnumerable的接口的.數據庫

2. IQueryable中有表達式樹, 這能夠看做是它的一個優點。因此,使用IQueryable操做時,好比對數據的過濾,排序等操做, 這些都會先緩存到表達式樹中. 當對數據庫操做真正發生時,它纔會將表達式樹執行來獲取數據。緩存

   這也就是說,好比選擇top 2兩行數據, 它會先在表達式樹中緩存這個過濾取top 2的操做。待到操做數據庫時,它就會在數據庫中篩選top 2數據。 =》 IQueryable 有延時加載機制, 它直接從數據庫中篩選數據.測試

3. IEnumerable, 它對數據進行操做時,和IQueryable不一樣,它會事先把全部的數據從數據庫獲取,放到內存中。而後,在內存中對這些數據進行篩選操做,包括過濾,排序等.  => IEnumerable 在內存中對數據進行篩選spa

 

咱們經過舉一個用Repository的例子來講明code

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中調用blog

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]

可見,它只從數據庫中取出了兩條數據

相關文章
相關標籤/搜索