Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Get documents for base class and inheriting classes in one query

I have a Mongo Collection of TaskBase documents. TaskBase has three subclasses. I created a collection manager for this collection (from a generic manager I already use). When I create, update or retrieve a subclass of TaskBase I get the correct type and no exception.

I created the following method:

public IEnumerable<TaskBase> GetTasksByAppId(string appId)
{
   var entityQuery = Query<TaskBase>.EQ(t => t.AppOId, appId);
   return this.MongoConnectionHandler.MongoCollection.Find(entityQuery).ToList();
}

When I run this I get an exception that Element [some element existing only in a subclass] is not a property or member of TaskBase I understand why I am getting this exception, I just don't know what to do about it. I would like to get a collection of ALL the types of tasks that could be associated with an App.

like image 230
Elad Lachmi Avatar asked Feb 12 '23 16:02

Elad Lachmi


1 Answers

You need to show the driver your class hierarchy. There are 2 options, the first using BsonKnownTypes and BsonDiscriminator attributes, the other using BsonClassMap.

Attributes

Decorate your base class with the specific derived classes you want to include (similar to what you would do in WCF). To tell the driver it's the root you also need BsonDiscriminator:

[BsonDiscriminator(RootClass = true)]
[BsonKnownTypes(typeof(ConcreteTask))]
public class TaskBase
{

}

BsonClassMap

BsonClassMap.RegisterClassMap<TaskBase>();
BsonClassMap.RegisterClassMap<ConcreteTask>();

Result

As a result, the document's type discriminator (_t) will be an array, and not a single value. In this case:

{ _t : ["TaskBase", "ConcreteTask"] }
like image 168
i3arnon Avatar answered Feb 15 '23 06:02

i3arnon