Not sure what exactly you want. There are essentially two types of updates in MongoDB: you can perform an atomic update, or replace the document.
Replacing the document is often easier, because it allows you to use standard C# operations to perform modifications and it will re-evaluate generated properties and the like:
var user = new User { Name = "John Doe", Quests =
new Dictionary<string, Tuple<string, string>> {
{ "hoho", new Tuple<string, string>("A", "A-Item") } } };
users.InsertOneAsync(user).Wait();
user.Quests = new Dictionary<string, Tuple<string, string>> {
{ "hoho Modified", new Tuple<string, string>("B", "B-Item") } };
users.ReplaceOneAsync(p => p.Id == user.Id, user);
However, it is sometimes required to use atomic modifiers, like $push
, $pull
, $set
, $addToSet
, etc. because of concurrency concerns. I generally consider it a bad idea to perform complex operations on complex embedded objects this way, because there is a high likelihood the object's consistency (in the ACID sense, or 'object invariants') can't be checked.
Suppose a user should not be allowed to have more than 3 active quests at a time, who ensures this rule is observed? That is normally the code's responsibility, and complex invariants can't be checked by the database.
If you still want to use those atomic operators, I suggest you ask a new question because there it really depends on the details (the dictionary, by default, is serialized as a document, the tuple as an array, and they require different atomic modifiers in MongoDB). For example, to add a new item to the dictionary, use $set
:
users.UpdateOneAsync(p => p.Id == user.Id,
Builders<User>.Update.Set("Quests.hoho Modified",
new Tuple<string, string>("B", "B-Item")));