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" 
    } 
  ] 
} 

使用官方 10gen C# 驱动程序时,保存/更新整个 Division 的最佳方法是什么?(最新的 0.9 版本。)

我正在使用 Update.AddToSetWrapped 添加部门,这很好,但我也希望能够根据他们的 _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使用修改后的分区。这可行,但显然并不理想,因为它执行两个单独的更新。

4

1 回答 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))
);

这里发生的关键事情是:

  1. Update.Set 中“$”的使用
  2. 由于 Update.Set 需要 BsonValue 作为它的第二个参数,我们必须使用 BsonDocumentWrapper 来保存除法值(Create 的 IDivision 类型参数将序列化时的nominalType 设置为 IDivision,从而导致写入“_t”鉴别器)。
于 2010-12-07T17:08:16.890 回答