2

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.

1 Answer 1

3
+50

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();
Sign up to request clarification or add additional context in comments.

3 Comments

also, as I suggested to you in some previous question, you can look at my answer to this question stackoverflow.com/questions/70958926/… to get more ways to do it in particular to look at query analyzer nuget.
This works. However when I do unset, I get the value 1 in JSON serialized string. Is that expected?
which particular query do you see?

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.