왜 EF7에서 술어에 대한 매개 변수를 사용할 때 ToListAsync ()를 사용할 수 없습니까?

asp.net-core c# entity-framework-core

문제

현재 ASP.VNext 응용 프로그램의 저장소 패턴 을 구현 중입니다. 내가 비동기 및 필터링 할 수있는 방법을하고 싶습니다. 그래서 다음과 같은 인터페이스 방법을 고안했습니다.

Task<TEntity> GetOneAsync(Func<TEntity,bool> predicate);

이것을 (개인 DbContext 인스턴스 ctx 를 사용하여) 구현하고 싶습니다.

public async Task<MyEntity> GetOneAsync(Func<MyEntity,bool> predicate) 
{
    // compiler error
    return await ctx.MyEntities.Where(predicate).FirstOrDefaultAsync();
}

그러나 나는 다음과 같이 술어를 하드 코딩 할 때만 FirstOrDefaultAsync() 사용할 수 있습니다.

return await ctx.MyEntites.Where(e => e.Id == 1).FirstOrDefaultAsync();

술어를 전달할 때 async 옵션을 사용하지 않고 FirstOrDefault() 만 가져 FirstOrDefault() 비동기 메소드를 만들기 위해서는 필자가 작성해야한다.

public async Task<MyEntity> GetOneAsync(Func<MyEntity,bool> predicate) 
{
    // compiler error
    return await ctx.MyEntities.Where(predicate).FirstOrDefaultAsync();
}

이 문제와 관련하여 두 가지 질문이 있습니다.

  1. 조건 FirstOrDefaultAsync() 전달할 때 FirstOrDefaultAsync() 메소드에 액세스 할 수없는 이유는 무엇입니까?

  2. 내 솔루션 await Task.Run(synchronousMethod) FirstOrDefaultAsync() 호출로 동일한 동작을 얻을 await Task.Run(synchronousMethod) 사용합니까?

수락 된 답변

FirstOrDefaultAsyncIQueryable<T> 의 확장 메서드로 정의됩니다.

ctx.MyEntities.Where(e => e.Id == 1)IQueryable<MyEntity> 반환합니다.

ctx.MyEntities.Where(predicate)IEnumerable<MyEntity> 반환합니다. Queryable.Where 아닌 Enumerable.Where 확장 메서드를 호출하기 때문입니다.

그것을 작동 시키려면 predicateFunc<MyEntity, bool> 에서 Expression<Func<MyEntity, bool>> . 즉, predicate 는 더 이상 원하는 결과를 제공하는 함수가 아니라 해당 함수에 대한 설명이므로 Entity Framework에서 SQL로 변환 할 수 있습니다.

그리고 아니요, 작업 내에서 Func<MyEntity, bool> 을 사용하면 동일한 동작이 발생하지 않습니다. 그것은 필터링없이 db 서버의 행을로드하고 일치가 발견 될 때까지 db 클라이언트에서 각각을 평가합니다. 그러면 많은 오버 헤드가 추가됩니다.




아래 라이선스: CC-BY-SA with attribution
와 제휴하지 않음 Stack Overflow
이 KB는 합법적입니까? 예, 이유를 알아보십시오.
아래 라이선스: CC-BY-SA with attribution
와 제휴하지 않음 Stack Overflow
이 KB는 합법적입니까? 예, 이유를 알아보십시오.