2013-11-20 1 views
6

내가 가진이 LINQ 쿼리Entity Framework 6에서 간단한 조회를 위해 복잡한 SQL 쿼리를 생성하는 이유는 무엇입니까?

dbContext.Customers.Where(c => c.AssetTag == assetTag).Count(); 

또는

(from c in dbContext.Customers 
where c.AssetTag == assetTag 
select c).Count(); 

생성 된 SQL은

SELECT 
[GroupBy1].[A1] AS [C1] 
FROM (SELECT 
    COUNT(1) AS [A1] 
    FROM [dbo].[Customer] AS [Extent1] 
    WHERE (([Extent1].[AssetTag] = @p__linq__0) AND (NOT ([Extent1].[AssetTag] IS NULL OR @p__linq__0 IS NULL))) OR (([Extent1].[AssetTag] IS NULL) AND (@p__linq__0 IS NULL)) 
) AS [GroupBy1] 

왜 LINQ는 곳 문 간단한에 대한 복잡한 SQL을 생성 않습니다 입니까?

+2

'[AssetTag]'열이 'null'일 수 있습니까? –

+1

그게 복잡하지 않아, 그냥 null 범위에서 귀하의 전화를 보호하기 위해 성명을 만듭니다 – Claies

+0

Linq 또는 Lamda 에서이 SQL 쿼리를 얻을 수있는 방법을 말해 줄 수 있습니까? 이것은 일반적으로 귀하의 질문에 무관하지만 뭔가 점점 문제가 있습니다. –

답변

7

(C# 문자열과 동일), null == nullTrue으로 평가됩니다. 데이터베이스의 null == nullFalse으로 평가됩니다. 이 스크립트는 열 값과 매개 변수가 모두 null인지 또는 둘 다 null이 아니며 동일한 문자열 값을 갖고 있는지 확인합니다. (결과가 null null로 null을 비교할 때 SQL의 세계에 있기 때문에) SQL에서 해당 행을 반환하지 않습니다 AssetTag == null을 비교 조건이 있기 때문에 ANSI의 NULLS 설정으로이 방법으로 생성됩니다

WHERE 
    (
     -- neither the column nor the paramter are null and 
     -- the column and the parameter have the same string value 
     ([Extent1].[AssetTag] = @p__linq__0) AND 
     (NOT ([Extent1].[AssetTag] IS NULL OR @p__linq__0 IS NULL)) 
    ) 
    OR 
    (
     -- both the column value and the parameter are null 
     ([Extent1].[AssetTag] IS NULL) AND 
     (@p__linq__0 IS NULL) 
    ) 
+0

감사합니다 모두들 설명해 주려고합니다. –

6

. C# 개발자가 기대하는 것과 동일한 쿼리 동작을 유지하기 위해 EF는 확장 된 WHERE 절을 생성합니다. 이전 버전의 EF는 그렇게하지 않았기 때문에 ANSI NULLS 설정을 사용하는 데이터베이스에서는 작동하지 않았습니다.

조인, 프로젝션 등 .Count() 호출 전에 EF가 훨씬 더 복잡한 쿼리를 지원하기 때문에 GroupBy 프로젝션이 가능합니다. 따라서이 방법은 모든 시나리오에서도 작동하므로 더 일반적입니다.

+0

나는 그 범위를 설명하려고 시도 했었지만 그것에 대한 피상적 인 이해에도 불구하고 그것을 설명하는 방법을 몰랐습니다. +1 너무 우아하게 넣어. – AaronLS

+0

6 이전의 EF는 이것을하지 않습니다. – CrazyPyro

5

두 경우 모두 C# c.AssetTag == assetTag이 참일 수 있습니다. 그러나 SQL에서는 null과 비교할 때 항상 false입니다.

([Extent1].[AssetTag] IS NULL) AND (@p__linq__0 IS NULL)

8

이 EF6에서 데이터베이스가 null의 의미는 다음과 같습니다 우리는 C#을 비교 역학을 다음 쿼리를 생성 할 경우에 따라서 , 우리는 모두가 null의 경우 true로 평가 널 (null)을 보장하기 위해 추가 조건을 비교하여 추가해야합니다 디폴트의 ​​비교 시멘틱스 이것은 EF5의 기본 설정을 변경 한 것입니다. EF5에서이 깃발은 ObjectContext.ContextOptions.UseCSharpNullComparisonBehavior에 묻혀 있었고 기본적으로 EF는 Linq 대 객체 비교의 의미를 사용합니다. EF6에서는 DbContext에 DbContext.Configuration.UseDatabaseNullSemantics으로 표시됩니다. 더 자세한 정보를 찾을 수 있습니다 here

+2

링크 된 msdn 도움말 페이지에'DbContextConfiguration.UseDatabaseNullSemantics'의 기본값이 거짓이라고 나와 있습니다 - 그래서 EF6 데이터베이스에서 null 의미가 기본 비교 의미가 아닙니까? – springy76

관련 문제