可空字段上的 Cosmos DB IQueryable
Posted
技术标签:
【中文标题】可空字段上的 Cosmos DB IQueryable【英文标题】:Cosmos DB IQueryable on nullable fields 【发布时间】:2021-12-31 21:12:32 【问题描述】:我的模型中有这个字段:
public class Lead
....
public Guid? ClientId get; set;
当我尝试在这样的代码中使用IQueryable
过滤此字段时
var queryable = container.GetItemLinqQueryable<Lead>()
.OrderBy(l => l.Created)
.AsQueryable();
....
//Use a list of GUIDs to filter on
if (search.ClientId?.Any() == true)
queryable = queryable.Where(lead => lead.ClientId.HasValue && search.ClientId.Contains(lead.ClientId.Value));
return queryable;
我希望这会在转换为 SQL 时添加以下 WHERE
子句
WHERE IS_DEFINED(c.clientId) AND c.clientId IN ('some GUID', 'another GUID', 'and so on')
实际上这个 LINQ 语句变成了这个
SELECT VALUE root FROM root WHERE (root['clientId']['hasValue'] AND (root['clientId']['value'] IN ('e870a235-ccb0-4a78-81b3-05dce5ac8a7f'))) ORDER BY root['created'] ASC
当我运行代码时,即使容器中的字段中存在具有指定 GUID 的文档,查询在运行时也不会返回任何对象。据我在 Nuget 包管理器中看到的,我的项目使用的是最新版本的 Microsoft.Azure.Cosmos (3.23.0)。
我在 C# 代码中做错了什么?有什么办法可以让它工作吗?
【问题讨论】:
生成的 LINQ 查询有什么问题?您的 guid 列表是否没有出现在 IN 语句中?您想使用 IS_DEFINED 而不是使用的方法的任何特定原因? @jegtugado,问题是查询在运行时不返回任何对象,即使容器中的字段中有具有指定 GUID 的文档。如您所见,生成的 SQL 完全不正确,因为它假定存在hasValue
和 value
字段,但事实并非如此。
这种问题真的很难搞清楚。我建议直接将生成的查询运行到 Cosmos DB 以查看是否有任何结果。我的粗略猜测是将lead => lead.ClientId.HasValue && search.ClientId.Contains(lead.ClientId.Value)
转换为lead => lead.ClientId.HasValue && search.ClientId.Any(s => s == lead.ClientId.Value)
。祝你好运。
@jegtugado,谢谢,我会试试的。
@jegtugado,当我尝试使用Any
时出现此异常:“输入不是 IDocumentQuery 类型。,Windows/10.0.19043 cosmos-netstandard-sdk/3.23.1”
【参考方案1】:
通过在 Where
子句中强制转换为 Guid
来修复它:
if (search.ClientId?.Any() == true)
queryable = queryable.Where(lead => search.ClientId.Contains((Guid)lead.LeadRequest.ClientId));
【讨论】:
以上是关于可空字段上的 Cosmos DB IQueryable的主要内容,如果未能解决你的问题,请参考以下文章
如何获取 cosmos db 容器中所有文档的所有字段名称 [关闭]
Azure Cosmos DB:使用 UpsertDocumentAsync 违反唯一索引约束
Azure上找不到MongoDB?不妨试试Azure Cosmos DB