修补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中存在的字段进行更新