2010-12-10 3 views
6

IEnumerable을 구현하는 간단한 클래스를 작성하는 대신 사용자 지정 LINQ 공급자를 작성하면 어떤 이점이 있습니까? 예를 들어사용자 지정 LINQ 공급자를 쓰는 이유는 무엇입니까?

quesiton는 Linq2Excel 보여줍니다

var book = new ExcelQueryFactory(@"C:\Users.xls"); 
var administrators = from x in book.Worksheet<User>() 
        where x.Role == "Administrator" 
        select x; 

을하지만 IEnumerable을로 "순진"구현을 통해 이점은 무엇인가?

+0

linq-to-excel이 IQueryable에서 이익을 얻는 이유를 모르지만 코드를 훨씬 빠르게 만드는 경우가 있습니다. – CodesInChaos

답변

11

Linq 공급자의 목적은 기본적으로 데이터 원본의 기본 쿼리 언어로 Linq 식 표현 트리 (쿼리 장면 뒤에 빌드 됨)를 "변환"하는 것입니다. 데이터가 이미 메모리에있는 경우에는 Linq 공급자가 필요하지 않습니다. Linq 2 개체 괜찮습니다. 그러나, Linq를 사용하여 DBMS 나 클라우드와 같은 외부 데이터 저장소와 대화하는 것이 절대적으로 중요합니다.

쿼리 구조의 기본 전제는 데이터 소스의 엔진이 최대한 많은 작업을 수행하고 클라이언트가 필요로하는 데이터 만 반환해야한다는 것입니다. 이는 데이터 소스가 저장하는 데이터를 관리하는 방법을 가장 잘 알고 있다고 가정하고 데이터의 네트워크 전송은 상대적으로 시간이 많이 걸리므로 최소화해야합니다. 이제 실제로 두 번째 부분은 "클라이언트가 요청한 데이터 만 반환"입니다. 서버는 프로그램의 마음을 읽고 실제로 필요한 것을 알 수 없습니다. 그것은 단지 요구되는 것을 줄 수 있습니다. 여기 지능형 Linq 제공 업체가 절대적으로 "순진한"구현을 날려 버리는 곳입니다. 표현식 트리를 생성하는 Linq의 IQueryable 측면을 사용하면 Linq 공급자는 표현식 트리를 DBS가 클라이언트가 Linq 문에서 요구하는 레코드를 반환하는 데 사용할 SQL 문으로 변환 할 수 있습니다. 순진한 구현은 클라이언트에 메모리 내 객체 목록을 제공하기 위해 광범위한 SQL 문을 사용하여 모든 레코드를 검색해야하며, 필터링, 그룹화, 정렬 등의 모든 작업은 클라이언트에 의해 수행됩니다.

예를 들어, Linq를 사용하여 기본 키를 사용하여 DB의 테이블에서 레코드를 가져 오는 경우를 가정 해 봅시다. Linq 공급자는 dataSource.Query<MyObject>().Where(x=>x.Id == 1234).FirstOrDefault()을 "SELECT TOP 1 * MyObjectTable WHERE Id = 1234"로 변환 할 수 있습니다. 그것은 0 개 또는 하나의 레코드를 반환합니다."순진한"구현은 아마도 서버에 "SELECT * FROM MyObjectTable"이라는 쿼리를 보낸 다음 Linq의 IEnumerable 측면 (메모리 클래스에서 작동)을 사용하여 필터링을 수행합니다. 성명서에서 1,000 만 개의 레코드가있는 테이블에서 0-1 개의 결과를 얻으려는 성명서가 있습니다.이 중 어느 것이 더 빨리 작업 할 것이라고 생각합니까?

7

LINQ-to-Objects (예 : foreach)와 같은 기능을 용도에 맞게 사용하려는 경우 LINQ 공급자를 작성할 필요가 없습니다. 대부분 메모리 내 목록에 적용됩니다.

은 SQL과 같이 쿼리의 식 트리를 분석하여 쿼리를 다른 것으로 변환하려는 경우 LINQ 공급자를 작성해야합니다. 당신이 언급 한 ExcelQueryFactory는 OLEDB-Connection과 함께 작동하는 것처럼 보입니다. 이것은 아마도 데이터를 쿼리 할 때 전체 Excel 파일을 메모리에로드 할 필요가 없다는 것을 의미합니다.

3

일반적인 성능. 어떤 종류의 색인이있는 경우 간단한 IEnumerable<T>에서 가능한 것보다 훨씬 빠르게 쿼리를 수행 할 수 있습니다.

Linq-To-SQL은 그 좋은 예입니다. 여기에서는 SQL 서버가 이해할 수 있도록 linq 문을 다른 것으로 변환합니다. 그래서 서버는 필터링, 정렬, ... 인덱스를 사용하고 linq-to-objects를 사용하여 클라이언트에게 전체 테이블을 보낼 필요가 없습니다.

하지만 너무 유용 할 수 있습니다 간단 경우가 있습니다

당신은 .Where(x=>(x.Time>=now)&&(x.Time<=tomorrow)) 같은 범위 쿼리가 많이 최적화 할 수있는 때에 프로퍼티 Time 이상 트리 인덱스를 가지고 있고, 반복 할 필요가없는 경우 열거 가능한 모든 항목.

1

LINQ는 가능한 한 최대 지연 실행을 제공하여 성능을 향상시킵니다.

IEnumurable <> 및 IQueryable <>는 완전히 다른 프로그램 구현을 제공합니다. IQueryable은 실제로 좋은 성능을 제공하는 표현식 트리를 동적으로 작성하여 네이티브 쿼리를 제공합니다. IEnumurable. 우리는 우리가 var 키워드를 사용할 수 있으며, 동적으로 가장 적합한 유형을 초기화합니다 확실하지 않은 경우

http://msdn.microsoft.com/en-us/vcsharp/ff963710.aspx

.

관련 문제