[CSHARP-2531] MongoDB C# mapping recursive object with bsonextraelements Created: 25/Feb/19  Updated: 19/Jun/19  Resolved: 07/May/19

Status: Closed
Project: C# Driver
Component/s: None
Affects Version/s: None
Fix Version/s: None

Type: Task Priority: Major - P3
Reporter: Jakub Dropia Assignee: Wan Bachtiar
Resolution: Done Votes: 0
Labels: question
Remaining Estimate: Not Specified
Time Spent: Not Specified
Original Estimate: Not Specified

Issue Links:
Duplicate

 Description   

I have following classes:

public class Property
{ 
    public string Description { get; set; }
    public object Value { get; set; }
 
    [BsonExtraElements]
    public IDictionary<string, Property> OtherData { get; set; }
} 
 
public class Device
{
   public string DeviceId { get; set; }
   public IDictionary<string, Property> Properties { get; set; }
}

What i want to achieve in json and map to those classes, is:

{  
   "DeviceId":"asd",
   "Properties":{  
      "PropertyA":{  
         "Description":"some info",
         "PropertyAB":{  
            "Description":"some info",
            "Value":"etc"
         }
      },
      "PropertyB":{  
         "Description":"some info",
         "Value":"etc"
      }
   }
}

So, as you can see, i want to map concrete Model "Property" in recursive way with ExtraElements usage. But above code will fail, as BsonExtraElements can be used only with IDictionary<string, object> interface. Also:

public class Property : IDictionary<string, Property>
{ 
    public string Description { get; set; }
    public object Value { get; set; }
}

doesn't work. And to be honest, this semantic would be the most desired. (no need to reach extra Property OtherData) But neither both of those semantics i cannot map properly. Is anyone tried something similar before? Any hints how to achieve this?



 Comments   
Comment by Wan Bachtiar [ 11/Jun/19 ]

you don't have any way to do that recursive, strict mapping with extrabsonelements

Hi Jakub,

Currently there is no built-in method in the driver that could do a recursive mapping of the same object as you described. i.e. IDictionary<string, Property> where Property contains Property.

In regards to BsonExtraElements, the purpose is for extra unknown elements. i.e. you don't know what the mapping is.

Regards,
Wan.

Comment by Jakub Dropia [ 24/May/19 ]

I know that. But this, unfortunately, isn't the strict mapping which i desired. I know the schema of data. I know, that it would be Property. But in other hand - i had recursive reference - So, Property object can have extra elements which are in exact schema as Property and so on. I know that i can model this using IDicionary<string, object> or BsonDocument, but then I'm loosing strict mapping to Property. 

So, if i understand correctly - you don't have any way to do that recursive, strict mapping with extrabsonelements?  

Comment by Wan Bachtiar [ 05/Apr/19 ]

But neither both of those semantics i cannot map properly. Is anyone tried something similar before? Any hints how to achieve this?

Hi Jakub,

For [BsonExtraElements] as mentioned in the manual BSON: Supporting Extra Elements, you must have a property of type BsonDocument (or IDictionary<string, object>) and you must identify that property as the one that should hold any extra elements that are found.

Currently the code assumes that all the values in BsonExtraElements dictionary are either instances of BsonValue or trivially convertible to BsonValue.

Have you tried using the following example for your use case ?

public class Property
{
    public string Description { get; set; }
    public object Value { get; set; }
 
    [BsonExtraElements]
    public BsonDocument OtherData { get; set; }
    //OR:
    //public IDictionary<string, object> OtherData { get; set; }
 
}
public class Device
{
    public ObjectId Id { get; set;}
    public string DeviceId { get; set; }
    public Property Properties { get; set; }
}

Regards,
Wan.

Comment by Jakub Dropia [ 18/Mar/19 ]

Any thoughts? 

Generated at Wed Feb 07 21:42:49 UTC 2024 using Jira 9.7.1#970001-sha1:2222b88b221c4928ef0de3161136cc90c8356a66.