No Name
No Name

Reputation: 79

Rendering MongoDB update document with nested objects in C#

I am trying to create a MongoDB update document in my C# application. I used to MongoDB.Driver and was able to do for a simple class.

 class MyTest
    {
        public string Name { get; set; } 
        public string Description { get; set; }
    }

  public static void Main(string[] args)
    {
        var v1 = Builders<MyTest>.Update
            .Set(t => t.Name, "TestName")
            .Set(t => t.Description, "TestDescription");

        var output = v1.Render(BsonSerializer.LookupSerializer<MyTest>(), new BsonSerializerRegistry()).ToString();
}

This produced expected output

{ "$set" : { "Name" : "TestName", "Description" : "TestDescription" } }

However, if I have a nested structure like this:

 class MyInnerClass
    {
        public string Id { get; set; }
    }
    class MyTest
    {
        public string Name { get; set; } 
        public string Description { get; set; }

        public List<MyInnerClass> InnerClasses { get;} = new List<MyInnerClass>();
    }

   
    public static void Main(string[] args)
    {
        var v1 = Builders<MyTest>.Update
            .Set(t => t.Name, "TestName")
            .Set(t => t.Description, "TestDescription")
            .Set(t => t.InnerClasses[0].Id, "TestId");

        var output = v1.Render(BsonSerializer.LookupSerializer<MyTest>(), new BsonSerializerRegistry()).ToString();
}

I get the exception when doing Render:

System.InvalidOperationException: 'Unable to determine the serialization information for t => t.InnerClasses.get_Item(0).Id.'

How to do this correctly?

Note that, I want the string representation of the update for my API call and not updating any real DB.

Upvotes: 2

Views: 311

Answers (1)

dododo
dododo

Reputation: 4857

Try:

        BsonClassMap.RegisterClassMap<MyTest>((b) =>
        {
            b.AutoMap();
            b.MapField(f=>f.InnerClasses);
        });

        var v1 = Builders<MyTest>.Update
                   .Set(t => t.Name, "TestName")
                   .Set(t => t.Description, "TestDescription")
                   .Set(t => t.InnerClasses[0].Id, "TestId");

        var output = v1.Render(BsonSerializer.LookupSerializer<MyTest>(), new BsonSerializerRegistry()).ToString();

another option, you can simply provide a raw query like:

        var v1 = Builders<MyTest>.Update
                   .Set(t => t.Name, "TestName")
                   .Set(t => t.Description, "TestDescription")
                   .Set("InnerClasses.0._id", "TestId");

        var registry = BsonSerializer.SerializerRegistry;
        var serializer = registry.GetSerializer<MyTest>();
        var output = v1.Render(serializer, registry).ToString();

Upvotes: 3

Related Questions