2012-10-17 34 views
5

Câu hỏi ban đầu được hỏi tại http://entityframework.codeplex.com/discussions/399499#post928179.IQueryable không triển khai IDbAsyncEnumerable

Chúc ngày vui vẻ! Xin vui lòng cho tôi biết nếu nó là sai chỗ để gửi câu hỏi này.

Tôi có một câu hỏi như sau:

IQueryable<Card> cardsQuery = 
    dataContext.Cards 
    .Where(predicate) 
    .OrderByDescending(kc => kc.SendDate) 
    .AsQueryable(); 

Sau đó, tôi thử:

Task<Card[]> result = cardsQuery.ToArrayAsync();

Và sau đó ngoại lệ tăng:

The source IQueryable doesn't implement IDbAsyncEnumerable<Models.Card>

tôi sử dụng phiên bản sửa đổi 'EF 5.x Máy phát DbCotext'.

Làm cách nào để tránh?

CẬP NHẬT

nhận xét quan trọng là tôi có phương pháp để sản xuất IQuerayble<Card> như sau:

class Repository { 
    public IQueryable<Card> GetKudosCards(Func<Card, bool> predicate) { 
    IEnumerable<KudosCard> kudosCards = kudosCardsQuery.Where(predicate); 
    return kudosCards 
      .OrderByDescending(kc => kc.SendDate) 
      .AsQueryable(); 
    } 
} 
+0

Arthur (tại http://entityframework.codeplex.com/discussions/399499#post928179) là đúng. Có một hoạt động khác giữa IQueryable <> và ToArrayAsync. Nó là ODataQueryOptions.ApplyTo từ gói OData. Nó thể hiện IQueryable theo các tham số OData của HTTP-request. Vì vậy, mã của tôi là đồng bộ trong khi ApplyTo là đồng bộ, phải không? –

+0

Tôi nghĩ rằng bạn nhận được điều này khi bạn cố gắng để viết một bài kiểm tra. Nếu bạn không muốn thay đổi mã sản xuất của mình, hãy làm theo các bước tại đây: http://msdn.microsoft.com/en-us/data/dn314429.aspx # async – Rikard

Trả lời

3

Sự cố như sau.

Tôi có một phương pháp:

class Repository { 
    public IQueryable<Card> GetKudosCards(Func<Card, bool> predicate) { 
    IEnumerable<KudosCard> kudosCards = kudosCardsQuery.Where(predicate); 
    return kudosCards 
      .OrderByDescending(kc => kc.SendDate) 
      .AsQueryable(); 
    } 
} 

Vấn đề là kudosCards có kiểu IEnumerable<KudosCard>. Điều đó ném ngoại lệ. Nếu tôi thay đổi loại biến vị ngữ thành Expression<Func<Card, bool> predicate thì mọi thứ sẽ hoạt động tốt.

6

điểm gọi AsQueryable là gì? Nếu bạn soạn truy vấn với các phương thức mở rộng bắt đầu từ bộ sưu tập nguồn IQueryable (ví dụ: DbSet, ObjectSet), truy vấn cũng sẽ là IQueryable.

Mục đích của AsQueryable là bọc một bộ sưu tập IEnumerable với một proxy/adapter IQueryable sử dụng nhà cung cấp LINQ có khả năng biên dịch truy vấn IQueryable thành truy vấn LINQ to Object. Điều này có thể hữu ích trong các tình huống khi bạn muốn sử dụng truy vấn dữ liệu không xác định.

Tại sao cuộc gọi AsQueryable lại cần thiết? Nếu bạn chỉ đơn giản là loại bỏ nó?

Cập nhật

Okey, bây giờ có vẻ như tôi hiểu vấn đề của bạn. Sau khi xem nhanh trên ODataQueryOptions.ApplyTo tôi nhận ra rằng nó chỉ mở rộng cây biểu thức cơ bản của truy vấn. Bạn vẫn có thể sử dụng nó để chạy truy vấn theo cách bạn muốn, tuy nhiên bạn cần một mẹo nhỏ để chuyển truy vấn trở lại thành generic.

IQueryable<Card> cardsQuery = 
    dataContext.Cards 
    .Where(predicate) 
    .OrderByDescending(kc => kc.SendDate); 


IQueryable odataQuery = queryOptions.ApplyTo(cardsQuery); 

// The OData query option applier creates a non generic query, transform it back to generic 
cardsQuery = cardsQuery.Provider.CreateQuery<Card>(odataQuery.Expression); 

Task<Card[]> result = cardsQuery.ToArrayAsync(); 
+0

Có vẻ như bạn đã đúng. Tôi có thể loại bỏ AsQueryable và đưa một cách rõ ràng OrderByDescending (...) vào IQueryable . Tuy nhiên, đây không phải là vấn đề. Vấn đề là tôi cần yêu cầu không đồng bộ với cơ sở dữ liệu. Tôi có nên chỉ cần gói ODataQueryOptions.ApplyTo vào Task.Factory.StartNew? Tôi không nghĩ đó là một quyết định tốt vì yêu cầu db sẽ bị chặn. –

+0

Tôi đã cập nhật câu trả lời của mình. – tamasf

+0

kudo của tôi cho một phương pháp phức tạp! Bạn đang nói đúng rằng vật liệu IQueryable xảy ra khi ToArray (Async) được gọi nhưng không có trong khi queryOptions.ApplyTo. Tuy nhiên, cách tiếp cận của bạn không hoạt động. Tôi có cùng lỗi: Nguồn IQueryable không triển khai IDbAsyncEnumerable . cardsQuery có loại {System.Linq.OrderedEnumerable'2 [Thẻ, System.DateTime]}. –

Các vấn đề liên quan