修补REST API以在.NET中部分更新MongoDB [英] Patch REST API to Partial Update MongoDB in .NET

查看:87
本文介绍了修补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<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屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆