[CSHARP-548] Partial Update in MongoDB C# Driver - Dictionary issue Created: 24/Aug/12  Updated: 20/Mar/14  Resolved: 27/Aug/12

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

Type: Bug Priority: Major - P3
Reporter: Nir Pinhasov Assignee: Robert Stam
Resolution: Done Votes: 0
Labels: dictionary, partial, update
Remaining Estimate: Not Specified
Time Spent: Not Specified
Original Estimate: Not Specified
Environment:

Windows 7, .Net Framework 4


Attachments: Text File Program.cs    

 Description   

Following the question here: http://stackoverflow.com/questions/12088370/partial-update-in-mongodb-c-sharp-driver-dictionary-issue

The problem occurs when trying to do a partial update (using UpdateBuilder) to an object which holds a dictionary, no matter what types of key-value. The dictionary is not serializing well (at least not as expected) when using ToBsonDocument().
When trying to fetch the object after the update, we get de-serialization errors (depends on the type), the one I get in the test program is: Input string was not in the correct format.



 Comments   
Comment by Nir Pinhasov [ 25/Aug/12 ]

Amazing, works like a charm. Thank you!

Comment by Robert Stam [ 24/Aug/12 ]

In your general purpose UpdateObject method you are serializing your TestDictionary property without providing any information about the expected type (what the driver calls nominalType), so the serialized form therefore has a "_t" property to identify the type. However, that's not how it gets serialized when the entire class gets serialized, so you end up with mismatched representations.

The easiest way to get all the element names and serialized representations right is to use the typed builders. For example, you could reimplement your UpdateObject method as:

private static bool UpdateObject<TDocument, TId, TField>(Expression<Func<TDocument, TId>> idLambda, TId id, Expression<Func<TDocument, TField>> fieldLambda, TField value)
{
    var query = Query<TDocument>.EQ(idLambda, id);
    var update = Update<TDocument>.Set(fieldLambda, value);
    var result = m_Collection.Update(query, update);
    return result.UpdatedExisting;
}

and the call it like this:

var updatedSuccessfully = UpdateObject((TestObject t) => t.Id, testObject.Id, (TestObject t) => t.TestDictionary, testObject.TestDictionary);

and then the driver would use all the available type information to generate the right query and update operations (including serializing your updated TestDictionary value in the proper form).

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