我试图找出在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;
答案 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或其他默认值来丢失字段,那么是否会导致错误。
假设以上所有内容,您可能必须自己建模类层次结构。我用两种不同的方式对此进行了建模:
使用物化数组指示每个文档的整个类层次结构。所以,[&#34; Animal&#34;,&#34;哺乳动物&#34;,&#34; Cat&#34;]。然后,当您想要所有哺乳动物时,可以使用WHERE "Mammal" IN c.class
查询。
最近,我已经切换到每种类型都有一个单独的字段。所以,isAnimal = true
,isMammal = true
和isCat = true
。这更像是一种mixin方法,但您仍然可以通过这种方式对类层次结构进行建模。