Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to get a reference to the parent object in a deserialized MongoDB document?

I hope someone can help. I'm getting to grips with the C# driver for MongoDB and how it handles serialization. Consider the following example classes:

class Thing
{
    [BsonId]
    public Guid Thing_ID { get; set; }
    public string ThingName {get; set; }
    public SubThing ST { get; set; }

    public Thing()
    {
        Thing_ID = Guid.NewGuid();
    }
}

class SubThing
{
    [BsonId]
    public Guid SubThing_ID { get; set; }
    public string SubThingName { get; set; }
    [BsonIgnore]
    public Thing ParentThing { get; set; }

    public SubThing()
    {
        SubThing_ID = Guid.NewGuid();
    }
}

Note that SubThing has a property that references its parent. So when creating objects I do so like this:

        Thing T = new Thing();
        T.ThingName = "My thing";

        SubThing ST = new SubThing();
        ST.SubThingName = "My Subthing";

        T.ST = ST;
        ST.ParentThing = T;

The ParentThing property is set to BsonIgnore because otherwise it would cause a circular reference when serialising to MongoDB.

When I do serialize to MongoDB it creates the document exactly how I expect it to be:

{
"_id" : LUUID("9d78bc5c-2abd-cb47-9478-012f9234e083"),
"ThingName" : "My thing",
"ST" : {
    "_id" : LUUID("656f17ce-c066-854d-82fd-0b7249c80ef0"),
    "SubThingName" : "My Subthing"
}

Here is the problem: When I deserialize I loose SubThing's reference to its parent. Is there any way to configure deserialization so that the ParentThing property is always its parent document?

like image 859
Pseudo Avatar asked Feb 19 '15 19:02

Pseudo


2 Answers

from mongodb web site

Implementing ISupportInitialize - The driver respects an entity implementing ISupportInitialize which contains 2 methods, BeginInit and EndInit. These method are called before deserialization begins and after it is complete. It is useful for running operations before or after deserialization such as handling schema changes are pre-calculating some expensive operations.

so, Thing will implement ISupportInitialize and the function BeginInit will stay empty and Endinit will contain St.ParentThing = this;

like image 90
Oren Haliva Avatar answered Nov 01 '22 20:11

Oren Haliva


At this level of abstraction, it's hard to give a definite answer.

One way is to have the class implement ISupportInitialize which offers a hook after de-serialization. That is probably the easiest solution for the problem at hand. Otherwise, the same link also shows how to write a custom serializer, but that shouldn't be required in this case.

like image 1
mnemosyn Avatar answered Nov 01 '22 18:11

mnemosyn