修补REST API以在.NET中部分更新MongoDB [英] Patch REST API to Partial Update MongoDB in .NET
问题描述
我有一个对象
{
"_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<SomeObject> update = Builders<SomeObject>.Update.Set(x => x.C, <value of property C>)
或者我可以对每个属性进行硬编码检查以查看其是否为空
IList<UpdateDefinition<SomeObject>> updates = new List<UpdateDefinition<SomeObject>>();
if (!string.IsNullOrEmpty(C)) {
updates.Add(UpdateDefinition<SomeObject> update = Builders<SomeObject>.Update.Set(x => x.C, <value of property C>));
}
if (!string.IsNullOrEmpty(C)) {
updates.Add(UpdateDefinition<SomeObject> update = Builders<SomeObject>.Update.Set(x => x.C, <value of property C>));
}
但是,如果我有很多属性和许多子属性,那么它很快就会变得非常大.另一个问题是,如果我将属性的值设置为有意为空,则由于它将字段查找为非空,因此它根本不会更新记录.
如何在.NET中动态地对MongoDB文档进行部分更新,以使我具有通用的PATCH API调用,该调用可以采用文档具有的任何参数,并且仅更新指定的属性?
我建议您避免依赖1.x旧版API,因为在2.x中也完全支持它,如下面的示例代码所示.
var client = new MongoClient();
var database = client.GetDatabase("test");
var collection = database.GetCollection<BsonDocument>("test");
var changesJson = "{ a : 1, b : 2 }";
var changesDocument = BsonDocument.Parse(changesJson);
var filter = Builders<BsonDocument>.Filter.Eq("_id", 1);
UpdateDefinition<BsonDocument> update = null;
foreach (var change in changesDocument)
{
if (update == null)
{
var builder = Builders<BsonDocument>.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<BsonDocument>();
//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<BsonDocument>(new BsonDocument("$set", changesDocument));
var result = collection.UpdateOne(filter, update);
信贷请给Robert Stam提供代码示例.
I have an object
{
"_id": "testobject",
"A": "First line",
"B": "Second line",
"C": "Third line"
}
I want to send a REST PATCH request to my API to only update one of these properties
{
"_id": "testobject",
"C": "Forth line"
}
This gets parsed into a class
public class SomeObject {
public string A { get; set; }
public string B { get; set; }
public string C { get; set; }
}
I now need to update the existing document in MongoDB but only updating the property C
.
I could create an update definition just for this one record
UpdateDefinition<SomeObject> update = Builders<SomeObject>.Update.Set(x => x.C, <value of property C>)
Or I could hard code a check on each property to see if it is empty
IList<UpdateDefinition<SomeObject>> updates = new List<UpdateDefinition<SomeObject>>();
if (!string.IsNullOrEmpty(C)) {
updates.Add(UpdateDefinition<SomeObject> update = Builders<SomeObject>.Update.Set(x => x.C, <value of property C>));
}
if (!string.IsNullOrEmpty(C)) {
updates.Add(UpdateDefinition<SomeObject> update = Builders<SomeObject>.Update.Set(x => x.C, <value of property C>));
}
However, if I have many properties and many sub properties this could get very large very fast. The other issue is that if I set the value of the property to be intentionally empty then it would not update the record at all due to it looking for the field to non-empty.
How can I dynamically do partial updates to MongoDB documents in .NET so that I have a generic PATCH API call that can take any of the parameters the document has and only update the properties specified?
I suggest that you avoid relying on 1.x legacy API, as it's perfectly supported in 2.x as well, as shown in the sample code below.
var client = new MongoClient();
var database = client.GetDatabase("test");
var collection = database.GetCollection<BsonDocument>("test");
var changesJson = "{ a : 1, b : 2 }";
var changesDocument = BsonDocument.Parse(changesJson);
var filter = Builders<BsonDocument>.Filter.Eq("_id", 1);
UpdateDefinition<BsonDocument> update = null;
foreach (var change in changesDocument)
{
if (update == null)
{
var builder = Builders<BsonDocument>.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<BsonDocument>();
//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<BsonDocument>(new BsonDocument("$set", changesDocument));
var result = collection.UpdateOne(filter, update);
Credits go to Robert Stam for providing the code sample.
这篇关于修补REST API以在.NET中部分更新MongoDB的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!