更新 Mongodb 中的字典

put*_*174 5 c# dictionary mongodb mongodb-.net-driver

我有一个存储以下数据的类:

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; }
}
Run Code Online (Sandbox Code Playgroud)

新用户的实例化如下:

await collection.InsertOneAsync(new User { Name = u, Pass = p, 
                     Quests = new Dictionary<string,Tuple<string,string>>() });
Run Code Online (Sandbox Code Playgroud)

我知道如何从创建的文档中查找和提取信息,但不知道如何推送和保存对文档的更改。大多数在线答案都是针对旧的 Mongodb C# 驱动程序,因此诸如Query或 之类的东西.save()不存在,或者我没有将正确的包包含到我的程序中。

我希望能够向词典添加和删除条目,然后保存对文档的更改。有什么建议么?

mne*_*syn 4

不确定你到底想要什么。MongoDB 中本质上有两种类型的更新:您可以执行原子更新,或替换文档

替换文档通常更容易,因为它允许您使用标准 C# 操作来执行修改,并且它将重新评估生成的属性等:

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);
Run Code Online (Sandbox Code Playgroud)

但是,出于并发性考虑,有时需要使用原子修饰符,例如$push、、、 等。我通常认为以这种方式对复杂的嵌入对象执行复杂的操作是一个坏主意,因为很可能无法检查对象的一致性(在 ACID 意义上,或“对象不变量” )。$pull$set$addToSet

假设不允许用户同时执行超过 3 个活动任务,谁来确保遵守此规则?这通常是代码的责任,数据库无法检查复杂的不变量。

如果您仍然想使用这些原子运算符,我建议您提出一个新问题,因为这实际上取决于细节(默认情况下,字典被序列化为文档,元组被序列化为数组,并且它们需要不同的原子修饰符在 MongoDB 中)。例如,要将新项目添加到字典中,请使用$set

users.UpdateOneAsync(p => p.Id == user.Id, 
  Builders<User>.Update.Set("Quests.hoho Modified", 
     new Tuple<string, string>("B", "B-Item")));
Run Code Online (Sandbox Code Playgroud)