이해합니다.AsEnumerable()LINQ 에서 SQL
-
27-09-2020 - |
문제
다음과 같은 LINQ SQL 쿼리:
var test = from i in Imports
where i.IsActive
select i;
해석 SQL 문을:
SELECT [t0].[id] AS [Id] .... FROM [Imports] AS [t0] WHERE [t0].[isActive] = 1
내가 원하는 몇 가지 작업을 수행하는 선택로 변환할 수 없는 SQL.그 대한 이해는 전통적인 방법으로 이를 수행하 do AsEnumerable()
따라서로 변환이 실행할 수 있는 객체입니다.
이 업데이트 코드:
var test = from i in Imports.AsEnumerable()
where i.IsActive
select new
{
// Make some method call
};
업데이트 SQL:
SELECT [t0].[id] AS [Id] ... FROM [Imports] AS [t0]
의 부족을 주의하는 절에서 SQL 문을 실행.
이 뜻은 전체"수입"표 캐시 메모리로?는 것이 성능에서 모든 경우 테이블이 포함된 많은 양의 레코드가?
하는 데 도움이 무엇인지 이해 실제로 일어나 뒤에서 여기입니다.
해결책
을 위한 이유 AsEnumerable 가
AsEnumerable(TSource)(페(TSource)) 선택하는 데 사용할 수 있습니 사이에 쿼리 구현할 때 순서 를 구현하는페이(T)또는 다른 세트의 공 쿼리 방법 이용 가능
그래서 때 당신은 전화 Where
방법을하기 전에,당신은 다른 Where
에서 방법 IEnumerable.Where
.그 Where
문 LINQ 로 변환하여 SQL,새로운 Where
가 IEnumerable
하나는 IEnumerable
, 를 열거 그것은 그 수익률이 일치하는 항목입니다.은 이유를 설명하는 다양한 SQL 생성됩니다.테이블에서 전체에서 데이터베이스하기 전에 Where
장에서 적용될 것입니다 당신의 두번째 버전의 코드입니다.이를 만들 수 있는 심각한 병기 때문에,목 전체를 테이블을 메모리에서,또는 나쁜 전체를 테이블의 것 사이에 여행하는 서버입니다.수 SQL 서버를 실행 Where
고 그것이 무엇 최고입니다.
다른 팁
는 점에 열거된 열거를 통해,데이터베이스 그 쿼리,그리고 전체 resultset 검색됩니다.
일부 및 일부 솔루션이 될 수 있습니다.고려
var res = (
from result in SomeSource
where DatabaseConvertableCriterion(result)
&& NonDatabaseConvertableCriterion(result)
select new {result.A, result.B}
);
말하자 또는 NonDatabaseConvertableCriterion 필요한 분야 C 에서 결과입니다.기 때문에 NonDatabaseConvertableCriterion 가 그 이름에서 알 수 있듯이,이를 수행으로 열거에 있습니다.그러나 생각해 보십시오:
var partWay =
(
from result in SomeSource
where DatabaseConvertableCriterion(result)
select new {result.A, result.B, result.C}
);
var res =
(
from result in partWay.AsEnumerable()
where NonDatabaseConvertableCriterion select new {result.A, result.B}
);
이 경우,고해상도 열거,쿼리되거나 그렇지 않으면 사용이 가능한 한 많은 작업을 전달되는 데이터베이스는 반환됩니다 충분히 계속 작업입니다.가정하면 그것은 참으로 정말 불가능을 다시 작성하도록 모든 작업을 전송할 수 있는 데이터베이스,이 될 수 있는 적당한 타협이다.
세 가지 구현 AsEnumerable
.
DataTableExtensions.AsEnumerable
확장 DataTable
을 주고 그것을 IEnumerable
인터페이스를 사용할 수 있도록 Linq 에 대하여 DataTable
.
Enumerable.AsEnumerable<TSource>
고 ParallelEnumerable.AsEnumerable<TSource>
이
AsEnumerable<TSource>(IEnumerable<TSource>)
메서드를 호출해도 아무런 영향이 없 다른 변경하는 것보다 compile-time 형식의 원천에서는 형식 를 구현하는IEnumerable<T>
하기IEnumerable<T>
자체입니다.
AsEnumerable<TSource>(IEnumerable<TSource>)
선택하는 데 사용할 수 있습니 사 쿼리를 구현할 때 시퀀스를 구현하는IEnumerable<T>
그러나 또 다른 설정의 공 쿼리 방법 유효합니다.예를 들어,일반적인 클래스Table
를 구현하는IEnumerable<T>
그리고 그것의 자신과 같은 방법Where
,Select
, 고SelectMany
, 전화Where
을 호출하는 공개Where
방법Table
.ATable
입력을 나타내는 데이터베이스 테이블 수Where
방법는 조건부 인수를 식으로 나 변환 트리 SQL 원격 실행합니다.면 원격 실행 원하지 않는다면,예를 들어이기 때문에 조건자를 호출하 지역 방법AsEnumerable<TSource>
메서드를 사용할 수 있습을 숨기기 사용자 지정 방법 대신 표준 쿼리 연산자 유효합니다.
에 다른 단어입니다.
이 있을 경우
IQueryable<X> sequence = ...;
에서 LinqProvider,다음과 같은 엔터티 프레임워크를 나
sequence.Where(x => SomeUnusualPredicate(x));
는 쿼리로 구성되고 서버에서 실행됩니다.이에 실패할 것이다 런타임이기 때문에 EntityFramework 알지 못하는 방법으로 변환 SomeUnusualPredicate
으로 SQL.
고 싶은 경우에는 문을 실행하 Linq 하는 개체를 대신,나
sequence.AsEnumerable().Where(x => SomeUnusualPredicate(x));
이제 서버에서 반환하는 모든 데이터 Enumerable.Where
에서 Linq 하는 개체를 대신 사용됩니다 쿼리를 제공업체의 구현합니다.
그것이 문제될 것은 없는 엔티티 프레임 워크를 알지 못 해석하는 방법 SomeUnusualPredicate
, 내 기능을 사용될 것이다.(그러나,이것은 비효율적인 방식 이후 모든 행에서 반환됩니다.)
내가 믿 AsEnumerable 는 컴파일러는 확장자를 사용하는 방법을 알려드리겠(이 경우에는 것에 대해 정의된페이는 대신 사람들을 위한 진행하고).쿼리 실행은 여전히이 지연된 때까지 당신은 전화 ToArray 또는 열거에 있습니다.