Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

IQueryable doesn't implement IDbAsyncEnumerable

The question was originally asked at http://entityframework.codeplex.com/discussions/399499#post928179 .

Good day! Please tell me if it is wrong place to post this question.

I have a query as follows:

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

Then I try:

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

And then exception rises:

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

I use modified version of 'EF 5.x DbCotext generator'.

How to avoid it?

UPDATE

Important remark is that I have method to produce IQuerayble<Card> as follows:

class Repository {
  public IQueryable<Card> GetKudosCards(Func<Card, bool> predicate) {
    IEnumerable<KudosCard> kudosCards = kudosCardsQuery.Where(predicate);
     return kudosCards
            .OrderByDescending(kc => kc.SendDate)
            .AsQueryable();
  }
}
like image 570
Alexander Myltsev Avatar asked Oct 17 '12 17:10

Alexander Myltsev


1 Answers

What is the point of calling AsQueryable? If you compose a query with the extension methods starting from an IQueryable source collection (e.g. DbSet, ObjectSet), the query will be IQueryable too.

The purpose of AsQueryable is to wrap an IEnumerable collection with an IQueryable proxy/adapter that uses a Linq provider that is capable of compiling IQueryable queries into a Linq to Object queries. This can be useful in scenarios when you would like to use inmemory data queries.

Why is the AsQueryable call necessary? What if you just simply remove it?

Update

Okey, now it seems I understand your problem. After a quick look on the ODataQueryOptions.ApplyTo I realized that it just extends the underlying expression tree of the query. You can still use it to run the query in the way you want, however you need a little trick to transform the query back to 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();
like image 191
tamasf Avatar answered Nov 15 '22 00:11

tamasf