2016-07-03 2 views
1

ASP.NET MVC를 Entity Framework와 함께 사용하고 있습니다. "AllUserData"라는 엔티티가 있습니다. "Genres"라는 두 번째 엔티티가 있습니다. 테이블의 각 행은 장르입니다.탐색 속성이있는 ToListAsync() 사용

이 두 엔티티는 일대 다 관계가 있습니다. 그래서 "AllUserData"클래스의 클래스 정의에서, 나는 public 가상 ICollection PreferredGenres {get; 세트; }

나는 성공적으로 내가 비주얼 스튜디오는 말한다

AllUserData aud = db.AllUserData.Single(b => b.UserId == currentUserId); 
var chosengenres = await aud.PreferredGenres.ToListAsync() 

는 "ICollection에이 'ToListAsync'에 대한 정의가 포함되어 있지 않습니다 사용할 수 없습니다 그러나

AllUserData aud = db.AllUserData.Single(b => b.UserId == currentUserId); 
var chosengenres = aud.PreferredGenres.ToList() 

를 사용하여 각 사용자가 선호하는 장르를 읽을 수 있어요 및 최상의 확장 메서드 과부하 'QueryableExtensions.ToListAsync (IQueryable)'형식의 수신기가 필요합니다. 'IQueryable'

왜 이런 일이 발생합니까? 두 경우의 차이점은 ToList()를 사용하고 ToListAsync()를 사용한다는 것입니다.

비동기 메서드를 탐색 속성과 함께 사용할 수 있습니까? 실생활 애플리케이션에는 다양한 개체간에 관계가있는 경우가 많이 있습니다. 이러한 관계를 사용하여 속성에 액세스 할 때 비동기 메서드를 사용할 수 있습니까? 이것 주위에 어떤 방법이 있습니까? 나는 가능한 한 비동기 적으로 일을하고 싶습니다.

답변

0

좋아, 엔티티 프레임 워크가 비동기 적으로 탐색 속성을 호출하는 것을 허용하지 않는 것 같습니다.

나에게 효과가 있었던 것은 처음부터 탐색 속성을로드하는 것입니다. (올바른 방향으로 나를 보내는 사용자 덕분에).

그래서 그 대신

AllUserData aud = await db.AllUserData.SingleAsync(b => b.UserId == currentUserId); 
var usergenres = await aud.PreferredGenres.ToListAsync(); 

의 작동하지 않는, 내가 대신이 작업을 수행 할 수 있습니다

AllUserData aud = await db.AllUserData.Include(p=>p.PreferredGenres).SingleAsync(b => b.UserId == currentUserId); 
var usergenres = aud.PreferredGenres.ToList(); 

이 방법을 첫 번째 쿼리가와 열망로드를 통해 데이터베이스에서 필요한 모든 정보를 끌어 묻습니다 .Include() .SingleAsync()의 사용자 때문에 비동기 적으로 수행됩니다. 다음 문은 .ToList()를 사용하지만 데이터가 이미로드되어 있으므로 데이터베이스로 두 번째 이동하면 안되므로 비동기라고는 중요하지 않습니다. 전체 작업이 이제는 비동기입니다.

나는 또한이 동일한 질문이 StackOverflow에서 이전에 요청되었다는 것을 깨달았습니다. 어떤 검색어를 사용했는지에 따라 찾기가 약간 어려웠습니다 : Entity Framework Designer First get navigation property as Tasks.선택한 대답은 네 가지 솔루션을 제공하며, 첫 번째 솔루션은 현재 내가 사용하고있는 솔루션과 유사합니다.

엔티티 클래스를 정의 할 때 탐색 속성을 비동기로 지정할 수도 있습니다.이 페이지의 "비동기 지연로드"절을 참조하십시오. here 예제 탐색은 단일 탐색 속성에 대해이 작업을 수행하는 방법을 보여줍니다. 나는 그것이 필요한 ICollection 네비게이션 프로퍼티에 대해서도 할 수 있을지 모르지만, 더 이상 파고 들지는 않았다.

2

탐색 속성이 Entity 속성의 표준 인 ICollection으로 선언되었으므로 컴파일러가 만족스럽지 않습니다.

그러나 탐색 컬렉션과 ToListAsync() 사이에 AsQueryable 또는 다른 Select() (필요한 경우)를 사용하여 IQueryable을 얻을 수 있습니다.

ToList()는 IEnumerable (ICollection 및 IQueryable 포함)에서 작동 할 수 있습니다. ToListAsync()는 IQueryable, 즉 VS의 메시지에서만 작동하도록 만들어졌습니다. "왜"구현 세부 사항에있을 수 있습니다.

+0

특히 IQueryable을 사용한다는 것은 ToListAsync가 서버에서 쿼리가 실행될 때까지 기다릴 필요가 없다는 것을 의미합니다.이 점이 중요합니다. 즉, 쿼리를 배경이 완성되고 완료되면 코드의 현재 지점으로 돌아옵니다. – daf

+0

실제로 여기에 게시하기 전에 "audwa.PreferredGenres.AsQueryable(). ToAsAsync()"를 기다렸습니다. VS가 불평하지는 않았지만 실제로 실행하려고 시도했을 때 런타임에 예외가 발생했습니다. 어떤 이유로 든 작동하지 않는 것 같습니다. Select()를 사용하는 대안이 있다고하셨습니다. ToListAsync() 전에 호출해야한다는 뜻인가요? – Gary

+0

FYI, AsQueryable()을 사용할 때받은 오류. ToListAsync()가 - "소스 IQueryable이 IDbAsyncEnumerable 을 구현하지 않았습니다. IDbAsyncEnumerable을 구현하는 소스 만 Entity Framework 비동기 작업에 사용할 수 있습니다. 자세한 내용은 http://go.microsoft.com/fwlink/?LinkId=287068을 참조하십시오. " – Gary

관련 문제