I have a class that stores the following data:
public class User
{
public ObjectId _id { get; set; }
public string Name { get; set; }
public string Pass { get; set; }
public Dictionary<string, Tuple<string, string>> Quests { get; set; }
}
New Users are instantiated with this:
await collection.InsertOneAsync(new User { Name = u, Pass = p,
Quests = new Dictionary<string,Tuple<string,string>>() });
I know how to find and pull information from created documents, but I don't know how to push and save changes to documents. Most of the answers online are for the old Mongodb C# driver, so things like Query
or .save()
don't exist, or I didn't include the right packages into my program.
I want to be able to add and remove entries to the Dictionary and then save the changes to the document. Any suggestions?
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")));