답변:
우선 , 인터페이스를 확장 하므로 "plain" 으로 수행 할 수있는 모든 작업은 .IQueryable<T>
IEnumerable<T>
IEnumerable<T>
IQueryable<T>
IEnumerable<T>
다만이 GetEnumerator()
반환 방법 Enumerator<T>
당신이 호출 할 수있는 MoveNext()
일련의 반복하는 방법을 T를 .
어떤 IQueryable<T>
이있다 IEnumerable<T>
하지 않습니다 특히-한 두 가지 속성은있는 포인트 쿼리 제공자 (예를 들어, SQL 공급자에 대한 LINQ)과 또 다른 하나를 가리키는 쿼리 식 표현 IQueryable<T>
될 수있는 런타임에 이동 추상 구문 트리로 객체를 주어진 쿼리 공급자가 이해합니다 (대부분의 경우 예외가 발생하지 않고 LINQ to SQL 공급자에게 LINQ to SQL 식을 제공 할 수 없음).
표현식은 단순히 오브젝트 자체의 상수 표현식이거나 구성된 쿼리 연산자 및 피연산자 세트의 더 복잡한 트리 일 수 있습니다. 쿼리 공급자 IQueryProvider.Execute()
또는 IQueryProvider.CreateQuery()
메서드가 전달 된 Expression 과 함께 호출 된 다음 쿼리 결과 또는 다른 결과 IQueryable
가 각각 반환됩니다.
AsQueryable()
열거 형을 쿼리 가능 객체로 캐스팅하고 IQueryable
인터페이스를 구현하면 ConstantExpression
반환 EnumerableQuery
합니다. 그렇지 않으면 반환 된 객체 에서 참조되는로 래핑됩니다 .
가장 큰 차이점은 델리게이트 대신 객체 를 IQueryable<T>
가져 오는 LINQ 연산자 Expression
는 예를 들어 조건 자 또는 값 선택기와 같이받는 사용자 지정 쿼리 논리가 메서드에 대한 델리게이트가 아닌 식 트리의 형식임을 의미합니다.
IEnumerable<T>
메모리 내에서 반복되는 시퀀스 작업에 유용하지만 IQueryable<T>
데이터베이스 또는 웹 서비스와 같은 원격 데이터 소스와 같은 메모리 부족을 허용합니다.쿼리 실행이 "in process"에서 수행되는 경우 일반적으로 필요한 것은 쿼리의 각 부분을 실행하는 코드 (코드)입니다.
실행이 프로세스 외부에서 수행 되는 경우 LINQ 공급자가 LDAP 쿼리이든 관계없이 LINQ 공급자가 메모리 부족 실행에 적합한 형식으로 변환 할 수 있도록 쿼리 논리를 데이터로 나타내야합니다. SQL 또는 무엇이든.
더 :
이것은 YouTube 의 멋진 비디오 로서 이러한 인터페이스가 어떻게 다른지 보여줍니다.
아래는 그것에 대한 긴 해답입니다.
기억해야 할 첫 번째 중요한 점은 IQueryable
인터페이스가에서 상속 받으 IEnumerable
므로 무엇이든 IEnumerable
할 수있는 IQueryable
것입니다.
많은 차이점이 있지만 가장 큰 차이점을 만드는 하나의 큰 차이점에 대해 논의하겠습니다. IEnumerable
interface는 LINQ
또는 Entity 프레임 워크를 사용하여 컬렉션을로드 하고 컬렉션에 필터를 적용하려는 경우에 유용합니다 .
IEnumerable
엔티티 프레임 워크와 함께 사용되는 아래 간단한 코드를 고려하십시오 . 사용하고 Where
그 기록을 얻기 위해 필터 EmpId
입니다 2
.
EmpEntities ent = new EmpEntities();
IEnumerable<Employee> emp = ent.Employees;
IEnumerable<Employee> temp = emp.Where(x => x.Empid == 2).ToList<Employee>();
여기서 필터는 IEnumerable
코드가 있는 클라이언트 측에서 실행됩니다 . 즉, 모든 데이터는 데이터베이스에서 가져온 다음 클라이언트에서 EmpId
is로 스캔하고 레코드를 가져옵니다 2
.
그러나 이제 아래 코드가로 변경 IEnumerable
되었습니다 IQueryable
. 서버 측에서 SQL 쿼리를 작성하고 필요한 데이터 만 클라이언트 측으로 전송합니다.
EmpEntities ent = new EmpEntities();
IQueryable<Employee> emp = ent.Employees;
IQueryable<Employee> temp = emp.Where(x => x.Empid == 2).ToList<Employee>();
따라서 필터 로직이 실행되는 위치 IQueryable
와 차이 IEnumerable
가 있습니다. 하나는 클라이언트 쪽에서 실행되고 다른 하나는 데이터베이스에서 실행됩니다.
따라서 메모리 내 데이터 수집 IEnumerable
만 사용하는 것이 좋지만 데이터베이스와 연결된 데이터 수집을 쿼리하려면`IQueryable이 네트워크 트래픽을 줄이고 SQL 언어의 힘을 사용하므로 더 나은 선택입니다.
IEnumerable : IEnumerable은 메모리 내 컬렉션 (또는 로컬 쿼리) 작업에 가장 적합합니다. IEnumerable은 항목간에 이동하지 않으며 앞으로 만 수집됩니다.
IQueryable : IQueryable은 데이터베이스 또는 웹 서비스 (또는 원격 쿼리)와 같은 원격 데이터 소스에 가장 적합합니다. IQueryable은 다양한 흥미로운 지연된 실행 시나리오 (페이징 및 컴포지션 기반 쿼리 등)를 가능하게하는 매우 강력한 기능입니다.
따라서 메모리 내 컬렉션을 단순히 반복해야하는 경우 IEnumerable을 사용하십시오. Dataset 및 기타 데이터 소스와 같은 컬렉션을 조작해야하는 경우 IQueryable을 사용하십시오.
실제로 LINQ-to-SQL과 같은 ORM을 사용하는 경우
두 경우 모두 당신이 전화하지 않는 경우 ToList()
또는 ToArray()
다음 쿼리가 사용될 때마다 실행됩니다, 그래서 말하자면, 당신은이 IQueryable<T>
당신은 다음 쿼리는 데이터베이스의 4 배에 대해 실행됩니다 그것에서 4 목록 상자를 입력합니다.
또한 쿼리를 확장하는 경우 :
q.Where(x.name = "a").ToList()
그런 다음 IQueryable을 사용하면 생성 된 SQL에 "where name ="a "가 포함되지만 IEnumerable을 사용하면 데이터베이스에서 더 많은 역할을 가져오고 x.name ="a "검사가 .NET에 의해 수행됩니다.
언급 한 작은 테스트 도움이 될 아래에는 차이의 한 측면을 이해 IQueryable<T>
하고를 IEnumerable<T>
. 다른 사람의 게시물에 수정 사항을 추가하려고하는 이 게시물 에서이 답변을 재현 했습니다.
DB에서 다음 구조를 만들었습니다 (DDL 스크립트).
CREATE TABLE [dbo].[Employee]([PersonId] [int] NOT NULL PRIMARY KEY,[Salary] [int] NOT NULL)
레코드 삽입 스크립트 (DML 스크립트)는 다음과 같습니다.
INSERT INTO [EfTest].[dbo].[Employee] ([PersonId],[Salary])VALUES(1, 20)
INSERT INTO [EfTest].[dbo].[Employee] ([PersonId],[Salary])VALUES(2, 30)
INSERT INTO [EfTest].[dbo].[Employee] ([PersonId],[Salary])VALUES(3, 40)
INSERT INTO [EfTest].[dbo].[Employee] ([PersonId],[Salary])VALUES(4, 50)
INSERT INTO [EfTest].[dbo].[Employee] ([PersonId],[Salary])VALUES(5, 60)
GO
이제 목표는 Employee
데이터베이스의 테이블에서 상위 2 개의 레코드를 가져 오는 것이 었습니다 . Employee
데이터베이스의 테이블을 가리키는 콘솔 응용 프로그램에 ADO.NET 엔터티 데이터 모델 항목을 추가하고 LINQ 쿼리 작성을 시작했습니다.
IQueryable 경로 코드 :
using (var efContext = new EfTestEntities())
{
IQueryable<int> employees = from e in efContext.Employees select e.Salary;
employees = employees.Take(2);
foreach (var item in employees)
{
Console.WriteLine(item);
}
}
이 프로그램을 실행하기 시작했을 때 SQL Server 인스턴스에서 SQL 쿼리 프로파일 러 세션도 시작했으며 다음은 실행 요약입니다.
SELECT TOP (2) [c].[Salary] AS [Salary] FROM [dbo].[Employee] AS [c]
그것은 그 그냥 IQueryable
적용하는 스마트 충분 Top (2)
가 와이어를 통해 5 개 기록의 2 아웃을 제공하므로 데이터베이스 서버 측 자체에 절은. 클라이언트 컴퓨터 측에서는 추가 메모리 내 필터링이 전혀 필요하지 않습니다.
IEnumerable 경로 코드 :
using (var efContext = new EfTestEntities())
{
IEnumerable<int> employees = from e in efContext.Employees select e.Salary;
employees = employees.Take(2);
foreach (var item in employees)
{
Console.WriteLine(item);
}
}
이 경우 실행 요약 :
SELECT [Extent1].[Salary] AS [Salary]
FROM [dbo].[Employee] AS [Extent1]
이제 IEnumerable
5 개의 레코드가 모두 Salary
테이블에 표시되고 클라이언트 컴퓨터에서 인 메모리 필터링을 수행하여 상위 2 개의 레코드를 얻습니다. 따라서 더 많은 데이터 (이 경우 3 개의 추가 레코드)가 불필요하게 전송되었습니다.
다음은 비슷한 주제에 대한 글입니다. (아니오, 나는 보통 나 자신을 인용하지 않지만 이것들은 아주 좋은 기사입니다.)
"이 기사는 도움이됩니다 : LINQ-to-SQL에서 IQueryable과 IEnumerable .
'MSDN 문서에 따르면 IQueryable에 대한 호출은 대신 내부 식 트리를 작성하여 작동합니다. "IQueryable (Of T)을 확장하는 이러한 메서드는 쿼리를 직접 수행하지 않습니다. 대신, 해당 기능은 누적 쿼리를 나타내는 식 트리 인 Expression 개체를 작성하는 것입니다." '
식 트리는 C # 및 .NET 플랫폼에서 매우 중요한 구성입니다. (일반적으로 중요하지만 C #을 사용하면 매우 유용합니다.) 차이점을 더 잘 이해하려면 공식 C # 5.0 사양의 표현식 과 명령문 의 차이점에 대해 읽어 보는 것이 좋습니다 . 람다 미적분학으로 분기되는 고급 이론적 개념의 경우 표현식을 사용하면 메소드를 일류 객체로 지원할 수 있습니다. IQueryable과 IEnumerable의 차이점은이 지점을 중심으로합니다. IQueryable은 표현 트리를 구축하지만 IEnumerable은 Microsoft의 비밀 실험실에서 일하지 않는 사람들에게는 적어도 일반적인 용어는 아닙니다.
여기에 푸시 대 풀 관점의 차이점을 자세히 설명하는 또 다른 유용한 기사가 있습니다. "푸시"와 "풀"은 데이터 흐름의 방향을 나타냅니다. .NET 및 C #에 대한 반응성 프로그래밍 기법
다음은 명령문 람다와 식 람다의 차이점을 자세히 설명하고 C # 대리자, 식 트리 및 람다 문 대 람다 식 다시 방문 의 식 트레스 개념에 대해 자세히 설명하는 매우 유용한 기사입니다 . "
데이터베이스에서 검색된 데이터를 사용 IEnumerable
하고 IQueryable
조작합니다. IQueryable
에서 상속 IEnumerable
되므로 IQueryable
모든 IEnumerable
기능 이 포함됩니다 . 주요 차이점 IQueryable
과 IEnumerable
즉 IQueryable
반면 필터를 실행하는 질의 IEnumerable
질의 1 및 다음 조건에 기초하여 데이터를 필터링 실행한다.
아래에서 더 자세한 차별화를 찾으십시오.
IEnumerable
IEnumerable
System.Collections
네임 스페이스에 존재IEnumerable
서버 측에서 선택 쿼리를 실행하고 클라이언트 측에서 메모리에 데이터를로드 한 다음 데이터를 필터링IEnumerable
List, Array와 같은 메모리 내 컬렉션에서 데이터를 쿼리하는 데 적합합니다.IEnumerable
LINQ to Object 및 LINQ to XML 쿼리에 유용iQueryable
IQueryable
System.Linq
네임 스페이스에 존재IQueryable
모든 필터를 사용하여 서버 측에서 '선택 쿼리'를 실행합니다.IQueryable
원격 메모리 (예 : 원격 데이터베이스, 서비스) 컬렉션에서 데이터를 쿼리하는 데 적합합니다.IQueryable
LINQ to SQL 쿼리에 유용따라서 IEnumerable
일반적으로 메모리 내 컬렉션 IQueryable
을 처리하는 데 사용되는 반면 컬렉션을 조작하는 데 일반적으로 사용됩니다.
IEnumerable과 IQueryable은 모두 데이터 수집을 유지하고 데이터 수집 작업을 필터링하는 등의 데이터 조작 작업을 수행하는 데 사용됩니다. 여기에서 예제와 가장 좋은 차이를 찾을 수 있습니다. http://www.gurujipoint.com/2017/05/difference-between-ienumerable-and.html