I am trying to figure out best way to model class inheritance in DocumentDb. Say my classes are structured as
class A
property X
property Y
property Z
class B inherits from A
property W
Is there a built in support to handle this? If I use Lambda expressions in my client code, will they be able to distinguish between the types automatically?
Will the following query only return objects of type B back? Or will it also consider instances of base class A?
var bCollection = from o in client.CreateDocumentQuery<B>(collectionLink)
where X > 2
select o;
Is there a built in support to hand this? If I use Lambda expressions in my client code, will it be able to distinguish b/w the types automatically?
Yes, you can use lambda syntax in client side, as long as you specify the specific type in the generic method, as client.CreateDocumentQuery<YourType>(collectionLink).
Will following query only bring objects of type B back? Or will it also consider instances of base class A?
DocumentDB is a schemaless store and does not store type information. The overloaded generic methods provided in the client are syntactic sugar, to let you easily create queries. All queries are evaluated against json documents, which do not have type information.
Inheritance scenario
So, if you fire a query for a property which is present only in your derived class, you will get values corresponding only to your derived class. But, if the property you are querying on is in both base class and derived class, you'll get back both results. For example, in your case filtering on W would give you results of only class B, but filtering on X, Y or Z would give you values for both classes A and B.
Classes with shared schema in same collection
Note that this does not just happen in the base-derived class scenario. Same behavior would happen if you have 2 separate classes, which do not inherit each other, but have a property with the same name. Querying on that property will return results of both classes. For example, if you have 2 classes which are stored in the same collection:
class A1 { int x; }
class A2 { int x; }
Even if you form your query using the client.CreateDocumentQuery<A1>(collectionLink), results of both class A & B will be returned. As I mentioned earlier, the type specification in the client is just to make your life easier while forming the query.
I you want to be able to query different types of data, having shared schema elements, stored in the same collection - I would recommend having a separate property to store the type information manually and filtering on that property.
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")
}
The query, client.CreateDocumentQuery<A1>(collectionLink).Where(d => d.DataType == "A1" && d.x == "xvaluefilter") will now return only data for class A1.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With