【问题标题】:IQueryable doesn't implement IDbAsyncEnumerableIQueryable 没有实现 IDbAsyncEnumerable
【发布时间】:2012-10-17 17:33:41
【问题描述】:

这个问题最初是在http://entityframework.codeplex.com/discussions/399499#post928179 提出的。

美好的一天!请告诉我发布此问题的位置是否错误。

我有一个查询如下:

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

那我试试:

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

然后异常上升:

The source IQueryable doesn't implement IDbAsyncEnumerable&lt;Models.Card&gt;

我使用“EF 5.x DbCotext 生成器”的修改版本。

如何避免?

更新

重要的是我有方法产生IQuerayble&lt;Card&gt;如下:

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

【问题讨论】:

标签: entity-framework


【解决方案1】:

调用 AsQueryable 有什么意义?如果您使用从 IQueryable 源集合(例如 DbSet、ObjectSet)开始的扩展方法组成查询,则查询也将是 IQueryable。

AsQueryable 的目的是用 IQueryable 代理/适配器包装 IEnumerable 集合,该代理/适配器使用能够将 IQueryable 查询编译为 Linq to Object 查询的 Linq 提供程序。这在您想使用内存数据查询的场景中很有用。

为什么需要调用 AsQueryable?如果你只是简单地删除它呢?

更新

好的,现在看来我明白你的问题了。在快速查看ODataQueryOptions.ApplyTo 之后,我意识到它只是扩展了查询的底层表达式树。您仍然可以使用它以您想要的方式运行查询,但是您需要一些小技巧来将查询转换回通用查询。

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

【讨论】:

  • 看来你是对的。我可以删除 AsQueryable 并将 OrderByDescending(...) 显式转换为 IQueryable。不过,这不是问题。问题是我需要对数据库的异步请求。我应该简单地将 ODataQueryOptions.ApplyTo 包装到 Task.Factory.StartNew 吗?我认为这不是一个好的决定,因为 db-request 会阻塞。
  • 我对一个棘手的方法表示敬意!您说得对,IQueryable 物化发生在 ToArray(Async) 调用时发生,但在 queryOptions.ApplyTo 时没有发生。尽管如此,你的方法还是行不通。我有同样的错误:源 IQueryable 没有实现 IDbAsyncEnumerable。 cardQuery 的类型为 {System.Linq.OrderedEnumerable`2[Card,System.DateTime]}。
  • 感谢您的时间和努力!问题出在另一个地方。当我有 15 名声望时,我会投票赞成你的答案。
【解决方案2】:

问题如下。

我有一个方法:

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

问题是 kudosCards 的类型为 IEnumerable&lt;KudosCard&gt;。这会引发异常。如果我将谓词类型更改为Expression&lt;Func&lt;Card, bool&gt; predicate,那么一切正常。

【讨论】:

    【解决方案3】:

    我在使用 LinqKit 库表达式构建器时遇到了同样的问题,它最终生成了 AsQueryable(),非常令人惊讶的是,它发生在 XUnit 集成测试调用中。

    我对为什么在通过 Swagger 调用同一个 API 端点时没有发生同样的问题感到很恼火。

    原来我必须做一个基本的改变。 我不得不更换:

    using System.Data.Entity;
    

    与:

    using Microsoft.EntityFrameworkCore;   
    

    【讨论】:

      【解决方案4】:

      我在使用 LinqKit 库表达式构建器时遇到了同样的问题,它最终生成了 AsQueryable()
      非常令人惊讶的是,我在 XUnit 集成测试调用中发生了这种情况。

      我对为什么在通过 Swagger 调用同一个 API 端点时没有发生同样的问题感到很恼火。


      事实证明我必须做一些基本的改变。
      我不得不更换:

      using System.Data.Entity;
      

      与:

      using Microsoft.EntityFrameworkCore;
      

      在我调用LinqKit表达式方法的地方。

      【讨论】:

        猜你喜欢
        • 2019-02-09
        • 2014-12-05
        • 1970-01-01
        • 2020-06-02
        • 2011-10-09
        • 1970-01-01
        • 2013-04-25
        • 1970-01-01
        • 2017-04-07
        相关资源
        最近更新 更多