Welcome to OStack Knowledge Sharing Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
342 views
in Technique[技术] by (71.8m points)

c# - Updating Dictionary in Mongodb

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?

See Question&Answers more detail:os

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Answer

0 votes
by (71.8m points)

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")));

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome to OStack Knowledge Sharing Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

2.1m questions

2.1m answers

60 comments

57.0k users

...