Entity Framework 4 Single () 대 First () 대 FirstOrDefault ()


119

단일 항목을 쿼리하는 다양한 방법과 각 항목을 사용하는시기를 비교하는 데 시간을 낭비하고 있습니다.

누구든지이 모든 것을 비교하는 링크가 있습니까? 아니면 왜 다른 것을 사용하는지에 대한 빠른 설명이 있습니까? 내가 알지 못하는 운영자가 여전히 더 있습니까?

감사합니다.

답변:


205

다음은 다양한 방법에 대한 개요입니다.

  • Find ()-기본 키로 항목을 가져 오려는 경우. 항목을 찾을 수없는 경우 null을 반환합니다. 동일한 컨텍스트가 살아있는 동안 동일한 엔티티를 여러 번 가져와야하는 경우 중요한 효율성 요소가 될 수있는 데이터베이스로 이동하기 전에 컨텍스트에서 살펴볼 것입니다 (Yaron이 주석에서 지적했듯이).

  • Single ()-쿼리에서 정확히 하나의 항목이 반환 될 것으로 예상하는 경우. 쿼리가 정확히 하나의 항목을 반환하지 않으면 예외가 발생합니다.

  • SingleOrDefault ()-쿼리에서 0 개 또는 1 개의 항목이 반환 될 것으로 예상 할 때 (즉, 주어진 키를 가진 항목이 있는지 확실하지 않음). 쿼리가 0 개 또는 1 개의 항목을 반환하지 않으면 예외가 발생합니다.

  • First ()-쿼리에 의해 하나 이상의 항목이 반환 될 것으로 예상하지만 코드의 첫 번째 항목에만 액세스하려는 경우 (여기에서 쿼리에서 순서가 중요 할 수 있음). 쿼리가 하나 이상의 항목을 반환하지 않으면 예외가 발생합니다.

  • FirstOrDefault ()-쿼리에서 0 개 이상의 항목이 반환 될 것으로 예상하지만 코드의 첫 번째 항목에만 액세스하려는 경우 (즉, 주어진 키가있는 항목이 있는지 확실하지 않음)


1
시나리오에 따라 다릅니다. 주어진 쿼리에 대해 항상 db에서 단일 레코드를 다시 가져와야한다는 것을 알고 있다면 Single ()이 사용할 '올바른'레코드입니다. 다른 상황에서는 다른 것이 더 적절할 수 있습니다. 이전 버전의 EF에서는 단일 레코드를 예상하는 시나리오에서 작동하는 First () 및 FirstOrDefault ()로 제한되었지만 실제로는 해당 단일 레코드보다 더 많이 반환되는 경우 경고하지 않습니다. 그 상황.
Steve Willcock

1
감사. 더 이상 First ()가 필요하다는 것을 알 수 없으며 Single ()이 더 좋지 않을 것입니다. 밀도가 낮다면 First ()를 언제 사용 해야하는지 이해하고 이해할 수 있다고 확신합니다.
asfsadf

1
First ()는 주문한 항목 중 가장 높거나 가장 낮은 객체 만 검색하려는 경우에 가장 적합합니다. 예를 들어, 총 가치가 가장 높은 판매를 찾으십시오. Sales.OrderByDescending(s => s.TotalValue).First();
Mike Chamberlain

5
위의 모든 댓글은 중요한 차이를 보입니다. Find ()는 db를 누르기 전에 컨텍스트를 검색하는 유일한 방법입니다.
Yaron Levi

5
SQL 데이터베이스를 쿼리, 때 또 다른 점은 SingleSingleOrDefault동안이 개 기록 (제한 2)를 쿼리한다 First또는 FirstOrDefault1 (한계 1)를 쿼리합니다.
Bart Calixto 2015 년

22

나는 항상 사용하는 경향이 있습니다 FirstOrDefault. 성능에 대해 정말 까다 롭고 싶다면 FirstOrDefaultEF에서 사용해야합니다 . Under the Cover SingleOrDefault는 쿼리에서 top (2)을 사용합니다. 기준과 일치하는 두 번째 행이 있는지 확인해야하고 일치하는 경우 예외가 발생하기 때문입니다. 기본적으로 SingleOrDefault쿼리가 1 개 이상의 레코드를 반환하면 예외를 throw하고 싶다고 말합니다.


5
FirstOrDefault과 (와) 사이의 성능 차이를 측정 한 적이 SingleOrDefault있습니까? 대부분의 경우 조기 최적화라고 말하고 싶습니다.
Steven

내가 사용하는 경향이 Single()또는 SingleOrDefault()내가 무언가를 반환 할 때이 해야 에만 존재 하나 . 내가 그렇게하는 이유는 잘못 작성된 쿼리를 작성하여 버그를 찾아 내야하는 것 이상을 반환하는 것입니다. 적어도 내 생각에 이것은 시스템의 데이터를 일관되게 유지하는 데 도움이 될 것입니다. 물론 이것은 더 느리지 만 그다지 느리지 않다고 생각하며 그 대가를 지불 할 의향이 있습니다.
mortb

15

매우 간단 Single합니다. 단일 항목을 반환하고 항목이 없거나 둘 이상이면 예외를 throw합니다. First첫 번째 항목을 반환하거나 항목이 없을 때 던집니다. FirstOrDefault항목이없는 경우 첫 번째 항목을 반환하거나 기본값 ( null주어진 유형이 참조 유형 인 경우) 을 반환합니다 .

이것이 API가 가져야하는 동작입니다. 그러나 기본 구현은 다른 동작을 가질 수 있습니다. Entity Framework가이를 준수하는 동안 LLBLGen과 같은 O / RM도 null호출 할 때 반환 할 수 First있는데 이는 매우 이상한 일입니다. 이것은 디자이너 IMO의 매우 이상하고 완고한 결정이었습니다.


감사합니다 스티븐. 나는 아직도 왜 당신이 다른 것을 사용하는지 궁금합니다. 저는 항상 FirstOrDefault ()를 사용해 왔고 왜 제가 본 많은 새로운 예제가 Single ()으로 전환되었는지 궁금했습니다. Single ()로 전환해야하는 이유가 있습니까? 대신 고려해야 할 동일한 일을 수행하는 다른 사람이 있습니까?
asfsadf

7
코드가 "빠르게 실패"하는 것을 좋아한다면 First () 및 Single ()을 사용하여 예상되는 내용을 더 정확하게 말하도록하십시오 (그렇지 않으면 실패 할 수 있음)
Frank Schwieterman

3
나는 Frank에게 전적으로 동의합니다. 의도를 전달하는 것도 중요합니다. Single결과에 하나의 요소 만있을 것으로 예상한다는 것을 명확하게 표현합니다.
Steven

8

네 가지 방법은 각각 제자리를 가지고 있습니다. 실제로는 두 가지 다른 작업 만 있습니다.

  • 먼저-여러 항목이 포함 된 결과 집합을 예상하고 해당 집합의 첫 번째 항목을 제공합니다.
  • 단일-단일 결과를 기대하고 해당 항목을 줘.

xxxxOrDefault () 버전은 "빈 결과 집합을 예외적 인 상황으로 간주하고 싶지 않습니다."라고 덧붙입니다.


좋아, 그래서 First ()는 거의 유용하지 않은 것 같습니다. Single ()이 첫 번째 옵션이 아닌 시나리오를 생각해내는 데 어려움을 겪고 있습니다. 당신은 우연히 빠른 손을 가지고 있습니까? 감사.
asfsadf 2010-08-14

3
불행히도 많은 개발자는 First () 또는 FirstOrDefault ()를 순전히 방어 수단으로 사용하며 실제로 실제 문제를 숨길 가능성이있을 때 예외를 피할 것이라고 생각합니다.
Matt H

3

반면에 다음과 같이 핵심 논리로 이러한 메서드를 나눌 수 있습니다.

  • 메서드는 데이터베이스를 직접 쿼리합니다 : Single (), SingleOrDefault (), First (), FirstOrDefault ()
  • 메서드는 데이터베이스에 대해 쿼리를 실행하기 전에 캐시에서 검색을 수행합니다 . Find ()

특히 두 번째 경우의 일부 성능 세부 정보는 https://msdn.microsoft.com/en-us/data/hh949853.aspx?f=255&MSPPError=-2147217396#3 에서 확인할 수 있습니다.

또한 첫 번째 그룹에서는 복잡한 쿼리를 정의 할 수 있지만 Find () 메서드를 사용하면 검색을위한 엔터티 키만 제공 할 수 있습니다.


0

Single ()SingleOrDefault () 는 일반적으로 ID와 같은 고유 식별자에 사용되는 반면 First () 또는 FirstOrDefault () 는 일반적으로 여러 결과를 가질 수 있지만 "상위 1" 만 원하는 쿼리에 사용됩니다. .

Single () 또는 First () 는 결과가 반환되지 않으면 예외를 throw하고 SingleOrDefault ()FirstOrDefault () 는 예외를 포착하고 null 또는 default (ResultDataType)를 반환합니다.

당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.