gpt4 book ai didi

C# LINQ .Any 不适用于 DocumentDb CreateDocumentQuery

转载 作者:IT王子 更新时间:2023-10-29 04:20:01 27 4
gpt4 key购买 nike

我正在尝试查询具有某种类型产品的 Art。这是我的艺术模型:

  public string Title { get; set; }
public string Description { get; set; }
public List<Product> Products { get; set; }
public string PaintedLocation { get; set; }

从这里开始,我所做的就是执行以下 LINQ 查询:

List<Art> items = DocumentDbHelper.Client.CreateDocumentQuery<Art>(collection.DocumentsLink)
.Where(i => i.type == "art")
.Where(i => i.Products.Any(p => p.Name == productType))
.AsEnumerable()
.ToList();

我收到以下错误:

"Method 'Any' is not supported."

我转到代码引用的页面查看 what is supported但我没有看到它说不支持 Any(),所以我可能做错了。如有任何帮助,我们将不胜感激。

更新

这对我来说真的很奇怪,所以我将其分解以查看两个结果返回的内容,以便更好地调试问题:

List<Art> items = DocumentDbHelper.Client.CreateDocumentQuery<Art>(collection.DocumentsLink)
.Where(i => i.Id.Contains("art"))
.AsEnumerable()
.ToList();

items = items.Where(i => i.Products.Any(p => p.Name == productType))
.AsEnumerable()
.ToList();

出于某种原因,这有效,我不喜欢它,因为自从我将其转换为列表以来,它运行了查询两次 - 但这至少证明 Any() 和 Select() 在技术上应该有效.

最佳答案

针对 IQueryable<T> 的 LINQ 查询最大的困惑之一是它们看起来与针对 IEnumerable<T> 的查询完全相同。嗯,前者正在使用 Expression<Func<..>>每当后者使用Func<..>时,但除非使用显式声明,否则这不是那么明显并且似乎不重要。然而,巨大的差异出现在运行时。

一旦IEnumerable<T>查询已成功编译,在运行时它就可以工作,而 IQueryable<T> 则不是这种情况。一个IQueryable<T>查询实际上是一个表达式树,由查询提供程序在运行时处理。

从一方面来说这是一个很大的好处,从另一方面来说,由于查询提供程序在查询编译时不涉及(所有方法都由 Queryable 类作为扩展方法提供),因此无法知道提供者是否支持某些构造/方法,或者直到运行时才支持。使用 Linq to Entities 的人非常清楚这一点。让事情变得更困难的是,没有明确的文档说明特定查询提供程序支持什么,更重要的是,它不支持什么(正如您从提供的“支持什么”链接中注意到的)。

解决办法是什么? (以及为什么你的第二个代码有效)

技巧是根据 IQueryable<T> 编写最大可能的(即查询提供程序支持的)查询部分。 ,然后切换到IEnumerable<T>并完成其余的操作(记住,一旦编译, IEnumerable<T> 查询就可以工作)。切换由 AsEnumerable() 执行称呼。这就是为什么你的第二个代码可以工作 - 因为不受支持 Any DocumentDb 查询提供程序上下文中不再包含该方法。请注意ToList不需要调用,并且查询不会执行两次 - 事实上,这样就没有单个查询,而是两个查询 - 一个在数据库中,一个在内存中。

所以像这样就足够了:

List<Art> items = DocumentDbHelper.Client.CreateDocumentQuery<Art>(collection.DocumentsLink)
.Where(i => i.type == "art")
.AsEnumerable() // The context switch!
.Where(i => i.Products.Any(p => p.Name == productType))
.ToList();

最后,DocumentDb 查询提供程序真正支持什么

文档中还不太清楚,但答案是:确切(且唯一)其中包含的内容。换句话说,唯一支持的查询运算符(或者更好地说 QueryableEnumerable 扩展方法)是

  • 选择
  • 选择多个
  • 地点
  • 订购依据
  • 按降序排序

正如您所见,它非常有限。忘记连接和分组运算符,Any , Contains , Count , First , Last等等。唯一的好处是它很容易记住:)

我怎么知道呢?好吧,像往常一样,当文档中有些内容不清楚时,可以使用反复试验或反编译器。显然在这种情况下前者不适用,所以我使用了后者。如果您好奇,请使用您最喜欢的反编译器并检查内部类的代码 DocumentQueryEvaluator里面Microsoft.Azure.Documents.Client.dll .

关于C# LINQ .Any 不适用于 DocumentDb CreateDocumentQuery,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/33839854/

27 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com