修补REST API以部分更新.NET中的MongoDB

我有一个对象

{ "_id": "testobject", "A": "First line", "B": "Second line", "C": "Third line" } 

我想向我的API发送一个REST PATCH请求,只更新其中一个属性

 { "_id": "testobject", "C": "Forth line" } 

这会被解析成一个类

 public class SomeObject { public string A { get; set; } public string B { get; set; } public string C { get; set; } } 

我现在需要更新MongoDB中的现有文档,但只更新属性C

我可以为这一条记录创建一个更新定义

 UpdateDefinition update = Builders.Update.Set(x => xC, ) 

或者我可以对每个属性进行硬编码以查看它是否为空

 IList<UpdateDefinition> updates = new List<UpdateDefinition>(); if (!string.IsNullOrEmpty(C)) { updates.Add(UpdateDefinition update = Builders.Update.Set(x => xC, )); } if (!string.IsNullOrEmpty(C)) { updates.Add(UpdateDefinition update = Builders.Update.Set(x => xC, )); } 

但是,如果我有许多属性和许多子属性,这可能非常快。 另一个问题是,如果我将属性的值设置为故意为空,那么它根本不会更新记录,因为它查找非空的字段。

如何动态地对.NET中的MongoDB文档进行部分更新,以便我有一个通用的PATCH API调用,它可以获取文档所具有的任何参数,只更新指定的属性?

我建议你不要依赖1.x遗留API,因为它在2.x中也得到了完美的支持,如下面的示例代码所示。

 var client = new MongoClient(); var database = client.GetDatabase("test"); var collection = database.GetCollection("test"); var changesJson = "{ a : 1, b : 2 }"; var changesDocument = BsonDocument.Parse(changesJson); var filter = Builders.Filter.Eq("_id", 1); UpdateDefinition update = null; foreach (var change in changesDocument) { if (update == null) { var builder = Builders.Update; update = builder.Set(change.Name, change.Value); } else { update = update.Set(change.Name, change.Value); } } //following 3 lines are for debugging purposes only //var registry = BsonSerializer.SerializerRegistry; //var serializer = registry.GetSerializer(); //var rendered = update.Render(serializer, registry).ToJson(); //you can also use the simpler form below if you're OK with bypassing the UpdateDefinitionBuilder (and trust the JSON string to be fully correct) update = new BsonDocumentUpdateDefinition(new BsonDocument("$set", changesDocument)); var result = collection.UpdateOne(filter, update); 

积分转到Robert Stam提供代码示例。

您可以使用

 IMongoUpdate updateDoc = new UpdateDocument("$set", doc); collection.Update(Query.EQ("_id",id), updateDoc); 

但是,你应该小心。

如果您首先将文档反序列化为SomeObject,则所有字段都将获得其默认值(对于字符串为null,对于ints等为0)。 如果您使用该对象进行更新,则json字符串中不存在的字段将更新为其默认值。

如果你使用

 var bsonDoc = BsonSerializer.Deserialize(jsonString); IMongoUpdate updateDoc = new UpdateDocument("$set", bsonDoc); collection.Update(Query.EQ("_id",id), updateDoc); 

数据库中的文档将仅针对jsonString中存在的字段进行更新