首页 文章

使用官方C#驱动程序更新MongoDB中的嵌入式文档

提问于
浏览
5

如果我有一个包含嵌入式部门的公司集合:

{ 
  "_id": 1 
  "_t": "Company", 
  "Name": "Test Company" 
  "Divisions": [ 
    { 
       "_id": 1 
       "_t": "Division", 
       "Name": "Test Division 1" 
    }, 
    { 
       "_id": 2 
       "_t": "Division", 
       "Name": "Test Division 2" 
    } 
  ] 
}

使用official 10gen C# driver时保存/更新整个部门的最佳方法是什么? (最新的0.9版本 . )

我正在使用Update.AddToSetWrapped来添加Divisions,这很好用,但我也希望能够根据它们的_id更新文档 .

例如,如果我定义以下Update方法:

public void UpdateDivision(IDivision division) 
{ 
  var mongo = MongoServer.Create(_connectionString); 
  var database = mongo.GetDatabase(_databaseName); 
  var query = Query.EQ("_id", division.CompanyId); 
  var update = Update.AddToSetWrapped("Divisions", division); 
  database.GetCollection<Company>("Company") 
          .Update(query, update, UpdateFlags.Upsert, SafeMode.True); 
}

并称之为:

var division = GetDivisionById(1); 
division.Name = "New Name"; 
UpdateDivision(division);

然后将一个新的Division实例添加到集合中,因为虽然“_id”仍然是1,但Name是不同的,因此它是一个唯一的文档 .

那么有什么更新整个嵌入式文档的好方法呢?

直到我想出一个更好的解决方案,我将首先 $pull 原始分区然后 $addToSet 与修改后的分区 . 这有效,但显然不理想,因为它执行两个单独的更新 .

1 回答

  • 11

    您可以使用MongoDB的位置数组修改功能一次更新数组中的整个分区,如下所示:

    var division = GetDivisionById(1);
    division.Name = "New Name";
    // change any other properties of division you want
    collection.Update(
        Query.EQ("Divisions._id", 1),
        Update.Set("Divisions.$", BsonDocumentWrapper.Create<IDivision>(division))
    );
    

    这里发生的关键事情是:

    • 在Update.Set中使用"$"

    • 由于Update.Set需要BsonValue作为其第二个参数,我们必须使用BsonDocumentWrapper来保存除法值(要创建的IDivision类型参数将序列化时的nominalType设置为IDivision,这将导致"_t"鉴别器被写入) .

相关问题