繁体   English   中英

Linq to DocumentDb,关于子项的where子句

[英]Linq to DocumentDb, where clause on child

在我目前正在从事的项目中,我们已经意识到我们不应该像使用f.ex SQL Server中的表那样使用DocumentDb集合。 结果,我们现在将所有属于单个租户的实体都保留在一个集合中。

我们的代码库中已经有很多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();

以上查询结果一样!!

  • 这两个查询返回相同数量的TModel实例
  • 仅第二个示例返回的实例具有其属性。

为了使我的重构成功,我需要wrong ...正确:):由于我们重视linq的类型安全性,因此不能选择使用SQL。 改变我们的方法以暴露出Resource<T>对象将触摸大量的代码,因为它需要所有*.Property引用被1-3 *.Model.Property引用。

属于DocumentDb客户端的linq提供程序似乎存在问题。

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

编辑2015-09-24

生成的SQL查询为:

  • 正确: {"query":"SELECT VALUE root.Model FROM root WHERE ((root.Type = \\"DocumentType\\") AND (NOT root.Model.IsDeleted)) "}
  • 错误: {"query":"SELECT * FROM root WHERE ((root.Type = \\"DocumentType\\") AND (NOT root.Model.IsDeleted)) "}

另外,此问题已在GitHub上报告(并捡到): https : //github.com/Azure/azure-documentdb-net/issues/58

已确认这是SDK的问题。 修复程序已签入,将随下一个SDK发行版一起提供。

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

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM