programing tip

LINQ To 엔터티는 마지막 방법을 인식하지 못합니다.

itbloger 2020. 6. 23. 07:55
반응형

LINQ To 엔터티는 마지막 방법을 인식하지 못합니다. 정말?


이 쿼리에서 :

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 TOP(T-SQL에서는) 있지만 SELECT BOTTOM(아무것도없는 ) 것은 없다는 사실에 기인합니다 .

그래도 쉬운 방법이 있습니다. 내림차순으로 주문한 다음을 수행하십시오 First().

편집 : 다른 공급자는 아마도 다른 구현을 가질 SELECT TOP 1것입니다. 오라클에서는 아마도 더 비슷할 것입니다WHERE ROWNUM = 1

편집하다:

또 다른 덜 효율적인 대안- 나는 이것을 권장하지 않습니다! - .ToList()전에 데이터 를 호출 .Last()하여 해당 시점까지 구축 된 LINQ To Entities Expression을 즉시 실행 한 다음 .Last ()가 작동 .Last()합니다. 대신 LINQ to Objects Expression. (그리고 당신이 지적했듯이, 그것은 결코 사용되지 않을 수천 개의 레코드와 CPU 구체화 객체의 낭비를 가져올 수 있습니다)

다시 한 번이 작업을 수행하지 않는 것이 좋지만 LINQ식이 실행되는 위치와 시간의 차이를 설명하는 데 도움이됩니다.


대신 다음을 Last()시도하십시오.

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

Last()Linq 선택기로 교체OrderByDescending(x => x.ID).Take(1).Single()

Linq에서 선호하는 경우 이와 같은 것이 작동합니다.

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());
}

또 다른 방법은 OrderByDescending없이 마지막 요소를 가져 와서 모든 엔티티를로드합니다.

dbSet
    .Where(f => f.Id == dbSet.Max(f2 => f2.Id))
    .FirstOrDefault();

LINQ to Entities (및 데이터베이스)는 모든 LINQ 메소드를 지원하지 않기 때문입니다 (자세한 내용은 여기 참조 : http://msdn.microsoft.com/en-us/library/bb738550.aspx ).

여기서 필요한 것은 "마지막"레코드가 "먼저"가되도록 FirstOrDefault를 사용하는 방식으로 데이터를 주문하는 것입니다. 데이터베이스에는 일반적으로 "첫 번째"및 "마지막"과 같은 개념이 없으며, 가장 최근에 삽입 된 레코드가 테이블에서 "마지막"인 것과는 다릅니다.

이 방법은 문제를 해결할 수 있습니다

db.databaseTable.OrderByDescending(obj => obj.Id).FirstOrDefault();

AsEnumerable()Select 기능이 작동하기 전에 단일 기능을 추가 했습니다.
예:

return context.ServerOnlineCharacters
    .OrderByDescending(p => p.ServerStatus.ServerDateTime)
    .GroupBy(p => p.RawName).AsEnumerable()
    .Select(p => p.FirstOrDefault());

Ref: https://www.codeproject.com/Questions/1005274/LINQ-to-Entities-does-not-recognize-the-method-Sys

참고URL : https://stackoverflow.com/questions/7293639/linq-to-entities-does-not-recognize-the-method-last-really

반응형