How to deserialize specific properties of derived class array using mongo C# driver. Instances of abstract classes cannot be created

356 views
Skip to first unread message

sudhir v

unread,
Jul 7, 2016, 7:46:49 PM7/7/16
to mongodb-user

Note : I have posted this question on StackOverflow as well here. Please let me know if it is redundant and I will delete one. 


The mongo C# driver version I am using is 1.1. I have the code structured like shown below.


public abstract Class BaseClass
{
    public int BCProp {get; set;}
}

public class DerivedClass1 : BaseClass
{
    public int DCProp1 {get; set;}
}

public class DerivedClass2 : BaseClass
{
    public int DCProp2 {get; set;}
}

public class ClassOfInterest
{
    public int Prop1 {get; set;}

    // I want to bring back only certain values
    // from the elements in this array while deserializing
    public BaseClass[] ElementArray {get; set;}
}


Before inserting the documents into MongoDB, I use BsonClassMap to Register the classes and set the discriminator as Class Name with Namespace. So when I create an object of ClassOfInterest and the ElementArray is an array of type DerivedClass1 elements, when I insert it into the DB, the array elements have "_t" as "DerivedClass1". All that looks good according to the documentation aboutPolymorphic classes and Discriminators.

For some reason, I decided to deserialize only some of the properties of ClassOfInterest. I do not want to deserialize Prop1 and I want just the ElementArray, so I wrote code like this


// Here I am specifying that I am interested only in ElementArray
// A Element in ElementArray will be of type DerivedClass1 and will
// include both BCProp and DCProp1
FieldsBuilder _fb = new FieldsBuilder();
_fb.Include("ElementArray");
List<string> IncludedFields = new List<string>();
var dic = _fb.ToBsonDocument().ToDictionary();
IncludedFields.AddRange(dic.Keys.ToList());

// I am querying DB
MongoCollection<ClassOfInterest> mcoll = ActiveDb.GetCollection<ClassOfInterest>(COICollName);
List<ClassOfInterest> COIObjects = mcoll.FindAll().SetFields(IncludedFields.ToArray()).ToList();


The above works fine. The returned objects have only ElementArray and do not include Prop1. The discriminator worked and the returned objects have Elements of type DerivedClass1 in ElementArray.

Again, for some reason, I do not want to deserialize everything from DerivedClass1. So I do the below.


// Notice that I want to get back only BCProp in all ElementArray
FieldsBuilder _fb = new FieldsBuilder();
_fb.Include("ElementArray.BCProp");
List<string> IncludedFields = new List<string>();
var dic = _fb.ToBsonDocument().ToDictionary();
IncludedFields.AddRange(dic.Keys.ToList());

// I am querying DB
MongoCollection<ClassOfInterest> mcoll = ActiveDb.GetCollection<ClassOfInterest>(COICollName);
List<ClassOfInterest> COIObjects = mcoll.FindAll().SetFields(IncludedFields.ToArray()).ToList();


This time however, I get the error "Instances of abstract classes cannot be created"

What went wrong this time? If I ask for the whole ElementArray, it properly deserializes the Elements in Element Array to DerivedClass1. However, when I ask for specific property (Belongs to base class), I get the error.

Reply all
Reply to author
Forward
0 new messages