Linq to DocumentDb,where子句

Linq to DocumentDb, where clause on child

在我目前正在进行的一个项目中,我们已经意识到我们不应该使用 DocumentDb 集合,就好像它们等同于 f.ex [=70= 中的 table ] 服务器。因此,我们现在将属于单个集合中的单个租户的所有实体持久化。

我们的代码库中已经有很多 linq 查询,它们假设每个文档类型(聚合根)都保存在一个专用集合中。为了让过渡变得轻松,我着手重构我们的数据访问对象,以便其 api 继续推理聚合根,并在其实现中处理单个集合与专用集合。

我的方法是将聚合根包装在一个 Resource<T> 对象中,该对象派生自 Resource 并公开一个 Model 属性 以及一个 Type 属性。我想我将能够根据以下代码将 IQueryable<T> 暴露给使用代码:

        return _client.CreateDocumentQuery<Resource<TModel>>(_collection.DocumentsLink)
            .Where(x => x.Type == typeof(TModel).Name)
            .Select(x => x.Model);

初步测试表明这按计划进行,我自信地提交了我的更改。然而,在进行功能测试时,我们发现一些查询模型的所有属性都设置为默认值(即 null、0、false 等)。

我可以使用以下代码重现该问题:

        var wrong = _client.CreateDocumentQuery<Resource<TModel>>(_collection.DocumentsLink)
            .Where(x => x.Type == typeof(TModel).Name)
            .Select(x => x.Model)
            .Where(x => !x.IsDeleted)
            .ToArray();

        var correct = _client.CreateDocumentQuery<Resource<TModel>>(_collection.DocumentsLink)
            .Where(x => x.Type == typeof(TModel).Name)
            .Where(x => !x.Model.IsDeleted)
            .Select(x => x.Model)
            .ToArray();

以上查询的结果一样!!

为了让我的重构成功,我需要 wrong 是......正确的:) 退回到 SQL 不是一个选项,因为我们重视 linq 的类型安全。改变我们公开 Resource<T> 对象的方法会触及很多代码,因为它要求所有 *.Property 引用都被 *.Model.Property 引用替换。

DocumentDb 客户端中的 linq 提供程序似乎有问题。

我们使用Microsoft.Azure.DocumentDb版本1.4.1

编辑 2015-09-24

生成的 SQL 个查询是:

此外,此问题已在 GitHub 此处报告(并已发现):https://github.com/Azure/azure-documentdb-net/issues/58

这已被确认为 SDK 的问题。已签入修复程序并将随下一个 SDK 发布一起发布。

在此期间,您可以使用 SQL,或更改放置 WHERE 子句的位置。