使用MongoDB官方C#驱动程序时重新保存的预期更新行为

时间:2011-06-16 20:56:42

标签: c# mongodb mongodb-.net-driver

尝试了解重新保存以前保存的现有文档(来自3级对象图)的预期行为。更新是仅应用于顶级字段还是尝试遍历嵌套对象更改?

var models = _database.GetCollection<Model>("Models");
var model = models.FindOneAs<Model>(Query.EQ("_id", new ObjectId("4df7bce0dc1c792230912fda")));

// Apply various changes on multi-level object graph...

models.Save(model);

尝试上述操作时,嵌套更改未应用于db。

1 个答案:

答案 0 :(得分:0)

我为你的问题建立了测试:

这是我保存到mongodb中的文档(深度为3级数组):

{
  "_id": "4dfa48d1872b4a1a50f60033",
  "NestedLevels": [
    {
      "Name": "Nested1",
      "NestedLevels": [
        {
          "Name": "Nested2",
          "NestedLevels": [
            {
              "Name": "Nested3",
              "NestedLevels": []
            }
          ]
        }
      ]
    }
  ]

}

我从c#加载它,用另一个值更新Name = Nested3并保存回来,之后我从mongodb更新文档读取并实际更新。所以我猜你代码的其他部分存在问题。

顺便说一句:如果你需要我可以在这里发布c#中的完整测试。

<强>更新

测试用例:

    [TestMethod]
    public void MongodbTest()
    {
        var mongoServer = MongoServer.Create("mongodb://localhost:27020");
        var database = mongoServer.GetDatabase("StackoverflowExamples");
        var levels = database.GetCollection("levels");
        var level1 = new Level1();

        var nested1 = new LevelX() { Name = "Nested1" };
        var nested2 = new LevelX() { Name = "Nested2" };
        nested1.NestedLevels.Add(nested2);
        var nested3 = new LevelX() { Name = "Nested3" };
        nested2.NestedLevels.Add(nested3);

        level1.NestedLevels.Add(nested1);

        levels.Insert(level1);

        var item = levels.FindOneAs<Level1>();

        item.NestedLevels[0].NestedLevels[0].NestedLevels[0].Name = 
                                         "Changed nested level 3 name";

        levels.Save(item);

        var itemAfterUpdate = levels.FindOneAs<Level1>();

        Assert.AreEqual("Changed nested level 3 name", 
            itemAfterUpdate.NestedLevels[0].NestedLevels[0].NestedLevels[0].Name);

        levels.RemoveAll();
    }

文件类:

public class Level1
    {
        public Level1()
        {
            Id = ObjectId.GenerateNewId();
            NestedLevels = new List<LevelX>();
        }

        [BsonId]
        public Object Id { get; set; }

        public List<LevelX> NestedLevels { get; set; }
    }

    public class LevelX
    {
        public LevelX()
        {
            NestedLevels = new List<LevelX>();
        }

        public string Name { get; set; }

        public List<LevelX> NestedLevels { get; set; }
    }