적절한 Linq where 절 수있는 한 동일한 결과를

나는 일상 생활에서 상당한 양의 linq를 작성하지만 대부분 간단한 진술을합니다. where 절을 사용할 때 여러 가지 방법으로 작성할 수 있으며 각각 내가 알 수있는 한 동일한 결과를 얻습니다. 예를 들어;

from x in Collection
  where x.Age == 10
  where x.Name == "Fido"
  where x.Fat == true
  select x;

결과와 관련하여 최소한 이것과 동등한 것으로 보입니다.

from x in Collection
  where x.Age == 10 &&
        x.Name == "Fido" &&
        x.Fat == true
  select x;

구문과 다른 점이 실제로 있습니까? 그렇다면 선호하는 스타일은 무엇이며 왜 그렇습니까?



답변

두 번째 것은 컬렉션의 각 항목에 대해 평가 할 술어가 하나 있기 때문에보다 효율적입니다. 첫 번째 항목에서와 같이 첫 번째 술어를 모든 항목에 먼저 적용하고 결과 (이 시점에서 좁혀 짐)는 다음과 같습니다. 두 번째 술어 등에 사용됩니다. 패스마다 결과가 좁아 지지만 여전히 여러 패스가 필요합니다.

또한 연결 (첫 번째 방법)은 술어를 AND 처리하는 경우에만 작동합니다. 이와 같은 것은 x.Age == 10 || x.Fat == true첫 번째 방법으로는 작동하지 않습니다.


답변

편집 : LINQ to Objects는 내가 기대했던대로 작동하지 않습니다. 내가 방금 작성한 블로그 게시물에 관심이있을 수 있습니다 …


그것들은 소위 무엇이 될지에 따라 다릅니다-첫 번째는 다음과 같습니다.

Collection.Where(x => x.Age == 10)
          .Where(x => x.Name == "Fido")
          .Where(x => x.Fat == true)

후자는 다음과 같습니다.

Collection.Where(x => x.Age == 10 &&
                      x.Name == "Fido" &&
                      x.Fat == true)

실제로 실제로 어떤 차이점이 구현에 따라 달라집니다Where 지는 호출되는 있습니다. 그것이 SQL 기반 공급자라면 두 사람이 같은 SQL을 만들 것으로 기대합니다. 그것이 LINQ to Objects에 있다면, 두 번째는 더 적은 간접 레벨을 가질 것입니다 (4 개 대신 2 개의 반복자가있을 것입니다). 속도 측면에서 이러한 간접 수준이 중요한지 여부 는 다른 문제입니다.

일반적으로 여러 where절이 상당히 다른 조건을 나타내는 것처럼 느껴질 경우 (예 : 하나는 객체의 한 부분과 관련이 있고 하나는 완전히 별 개임) where여러 절을 사용하고 다양한 조건이 밀접하게 관련되어있는 경우 (예 : 특정 값) 최소값보다 크고 최대 값보다 작음). 기본적으로 약간의 성능 차이 전에 가독성을 고려할 가치가 있습니다.


답변

첫 번째가 구현됩니다.

Collection.Where(x => x.Age == 10)
          .Where(x => x.Name == "Fido") // applied to the result of the previous
          .Where(x => x.Fat == true)    // applied to the result of the previous

훨씬 더 간단하고 ( 아마도 더 빠를 것임) 반대로 :

// all in one fell swoop
Collection.Where(x => x.Age == 10 && x.Name == "Fido" && x.Fat == true)

답변

내가 달릴 때

from c in Customers
where c.CustomerID == 1
where c.CustomerID == 2
where c.CustomerID == 3
select c

from c in Customers
where c.CustomerID == 1 &&
c.CustomerID == 2 &&
c.CustomerID == 3
select c customer table in linqpad

내 고객 테이블에 대해 동일한 SQL 쿼리가 출력됩니다.

-- Region Parameters
DECLARE @p0 Int = 1
DECLARE @p1 Int = 2
DECLARE @p2 Int = 3
-- EndRegion
SELECT [t0].[CustomerID], [t0].[CustomerName]
FROM [Customers] AS [t0]
WHERE ([t0].[CustomerID] = @p0) AND ([t0].[CustomerID] = @p1) AND ([t0].[CustomerID] = @p2)

따라서 sql 로의 번역에는 차이가 없으며 다른 답변에서 람다 식으로 변환되는 방법을 이미 보았습니다.


답변

후드를 살펴보면 두 명령문이 다른 쿼리 표현으로 변환됩니다. 에 따라 QueryProviderCollection 이 멀리 최적화 여부 될 수 있습니다.

이것이 linq-to-object 호출 인 경우 여러 where 절은 서로 읽은 IEnumerable 체인으로 이어집니다. 단일 조항 양식을 사용하면 성능이 향상됩니다.

기본 공급자가 SQL 문으로 변환하면 두 변형이 모두 같은 문을 만들 가능성이 높습니다.