DocumentDb中的类继承

时间:2015-10-10 23:03:51

标签: azure-cosmosdb

我试图找出在DocumentDb中建模类继承的最佳方法。 假设我的课程结构为

class A
 property X
 property Y
 property Z

class B inherits from A
  property W

这是否有内置支持?如果我在客户端代码中使用Lambda表达式,它是否能够自动区分b / w类型?

以下查询是否只会返回B类对象?或者它还会考虑基类A的实例吗?

var bCollection = from o in client.CreateDocumentQuery<B>(collectionLink)
                  where X > 2

                  select o;

2 个答案:

答案 0 :(得分:2)

有内置的支持吗?如果我在客户端代码中使用Lambda表达式,它是否能够自动区分b / w类型?

是的,只要在泛型方法中指定特定类型client.CreateDocumentQuery<YourType>(collectionLink),就可以在客户端使用lambda语法。

以下查询是否只会将B类对象带回来?或者它还会考虑基类A的实例吗?

DocumentDB是一个无模式存储,不存储类型信息。客户端提供的重载泛型方法是语法糖,可以让您轻松创建查询。 所有查询都是针对没有类型信息的json文档进行评估的。

继承方案

因此,如果为仅在派生类中出现的属性触发查询,则将获得仅与派生类相对应的值。但是,如果您要查询的属性同时属于基类和派生类,那么您将获得两个结果。例如,在您的情况下,对W进行过滤会仅为您提供类B的结果,但对X, Y or Z进行过滤会为您提供类A和{{1}的值}}

同一集合中具有共享架构的类

请注意,这不仅发生在基础派生类场景中。如果有2个单独的类,它们不会相互继承,但具有相同名称的属性,则会发生相同的行为。查询该属性将返回两个类的结果。 例如,如果您有2个类存储在同一个集合中:

B

即使您使用class A1 { int x; } class A2 { int x; } 形成查询,A类和A类的结果也是如此。 B将被退回。正如我之前提到的,客户端中的类型规范只是为了让您在构建查询时更轻松。

我希望能够查询不同类型的数据,共享模式元素,存储在同一个集合中 - 我建议使用单独的属性手动存储类型信息并过滤该属性。

client.CreateDocumentQuery<A1>(collectionLink)

查询class DocumentDbData { string DataType; DocumentDbData(string type) { DataType = type;} } class A1 : DocumentDbData { string x; A1() : base("A1") } class A2 : DocumentDbData { string x; A2() : base("A2") } 现在只返回A1类的数据。

答案 1 :(得分:0)

我使用node.js而不是.NET,所以我不认识CreateDocumentQuery<B>语法。有没有办法检查.NET SDK发送的实际查询,以查看WHERE子句中是否添加了一些内容以将结果限制为B类型?或者,在没有您干预的情况下,您的文档中是否添加了_Type这样的字段?我非常怀疑你提供的查询条款是如此修改的。我不确定_Type字段是否已被添加,但我认为它不到50%。我的直觉只是<B>上的CreateDocumentQuery规范简单地将返回的对象强制转换为B类型。我不知道如果你的结果集包含A类对象,或者它将使用null或其他默认值来丢失字段,那么是否会导致错误。

假设以上所有内容,您可能必须自己建模类层次结构。我用两种不同的方式对此进行了建模:

  1. 使用物化数组指示每个文档的整个类层次结构。所以,[&#34; Animal&#34;,&#34;哺乳动物&#34;,&#34; Cat&#34;]。然后,当您想要所有哺乳动物时,可以使用WHERE "Mammal" IN c.class查询。

  2. 最近,我已经切换到每种类型都有一个单独的字段。所以,isAnimal = trueisMammal = trueisCat = true。这更像是一种mixin方法,但您仍然可以通过这种方式对类层次结构进行建模。

相关问题