2011-09-03 5 views
111

는 :LINQ To Entities가 Last 메서드를 인식하지 못합니다. 정말? 이 쿼리에서

public static IEnumerable<IServerOnlineCharacter> GetUpdated() 
{ 
    var context = DataContext.GetDataContext(); 
    return context.ServerOnlineCharacters 
     .OrderBy(p => p.ServerStatus.ServerDateTime) 
     .GroupBy(p => p.RawName) 
     .Select(p => p.Last()); 
} 

나는

public static IEnumerable<IServerOnlineCharacter> GetUpdated() 
{ 
    var context = DataContext.GetDataContext(); 
    return context.ServerOnlineCharacters 
     .OrderByDescending(p => p.ServerStatus.ServerDateTime) 
     .GroupBy(p => p.RawName) 
     .Select(p => p.FirstOrDefault()); 
} 

을 작동하려면 심지어 첫 번째 쿼리를 미러링, p.First()를 사용할 수없는이로 전환했다.

이렇게 견고한 ORM 시스템에는 왜 이러한 기본적인 제한이 있습니까? 제한이 결국은 SQL에 해당 쿼리를 번역하는 사실에 내려 와서 SQL은 SELECT BOTTOM (그런 일을) (T-SQL에서)를 SELECT TOP이 없습니다하지만 그건

+0

IEnumrable 개체를 새 변수에 저장 한 다음 variable.last()를 반환합니다. 그것은 효과가있을 것이다. –

답변

174

.

주위에는 쉬운 방법이 있습니다. 주문 내림차순 다음에 수행 한 것은 First()입니다.

편집 : 다른 공급자가 가능 아마 뭔가 될 것 오라클, SELECT TOP 1의 다른 구현을 것보다 같은 WHERE ROWNUM = 1

편집 :

또 다른 덜 효율적인 대안 - 난 몰라 이것을 추천해라! - .Last() 전에 데이터에 .ToList()을 호출하면 즉시 해당 지점까지 빌드 된 LINQ To Entities식이 실행되고 그 시점에서 .Last()이 효과적으로 실행되므로 .Last()가 작동합니다. 문맥 대신 LINQ to Objects 표현식. (그리고 당신이 지적했듯이 수천 개의 레코드를 가져오고 CPU 사용량이 낭비 될 것입니다.)

다시 말하지만이 두 번째 방법은 권장하지 않습니다. 및 LINQ 표현식이 실행될 때. 당신이 Linq에 그것을 할 prefert 경우 그 일을 할 것 같은

+0

및 LINQ To SQL은이 시나리오를 어떻게 처리합니까? – bevacqua

+1

@ 니코 : 그것은 또한 던졌습니다. – jason

+0

@Neil 네 ToList를 호출 할 수 있다는 것을 알고 있지만 데이터베이스에서 수천 개의 레코드 만 검색하여 5 개의 레코드로 필터링하지 마십시오. – bevacqua

12

Linq를 선택하여 OrderByDescending(x => x.ID).Take(1).Single()

뭔가를 Last()를 교체 대신 Last()

public static IEnumerable<IServerOnlineCharacter> GetUpdated() 
{ 
    var context = DataContext.GetDataContext(); 
    return context.ServerOnlineCharacters.OrderBy(p => p.ServerStatus.ServerDateTime).GroupBy(p => p.RawName).Select(p => p.OrderByDescending(x => x.Id).Take(1).Single()); 
} 
+0

이것은 나를 위해 완벽하게 작동했습니다. –

+1

.FirstOrDefault() 대신 .Take (1) .Single()을 사용해야하는 이유가 있습니까? –

+1

@TotZam 유효한 개수는 항목 수가 정확히 1이 아닌 경우 Single()이 예외를 던지기 때문에 .First()가됩니다. – MEMark

17

을,이 시도 :

model.OrderByDescending(o => o.Id).FirstOrDefault(); 
0

또 다른 방법은 OrderByDescending없이 마지막 요소를 가져와 모든 항목을로드하는 것입니다.

dbSet 
    .Where(f => f.Id == dbSet.Max(f2 => f2.Id)) 
    .FirstOrDefault(); 
관련 문제