2016-11-10 2 views
1

Ich habe ein ObjektPatch-REST-API Teil-Aktualisierung MongoDB in .NET

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

Ich möchte nur eine dieser Eigenschaften aktualisieren, um eine REST-PATCH Anfrage an meine API senden

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

Diese wird in eine Klasse analysiert

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

ich jetzt das vorhandene Dokument in MongoDB zu aktualisieren, sondern nur die Aktualisierung der Eigenschaft benötigen C.

I

für diesen einen Datensatz nur ein Update-Definition erstellen könnte
UpdateDefinition<SomeObject> update = Builders<SomeObject>.Update.Set(x => x.C, <value of property C>) 

Oder ich könnte schwer, einen Scheck auf jede Eigenschaft kodieren, um zu sehen, ob es

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>)); 
} 

jedoch leer ist, wenn ich Viele Eigenschaften und viele Untereigenschaften können sehr schnell sehr groß werden. Das andere Problem ist, dass wenn ich den Wert der Eigenschaft absichtlich leer festlegen würde, würde es den Datensatz überhaupt nicht aktualisieren, weil er nach dem Feld sucht, das nicht leer ist.

Wie kann ich dynamisch partielle Updates für MongoDB-Dokumente in .NET durchführen, so dass ich einen generischen PATCH-API-Aufruf habe, der beliebige der Parameter des Dokuments annehmen und nur die angegebenen Eigenschaften aktualisieren kann?

Antwort

1

Sie

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

jedoch verwenden können, sollten Sie vorsichtig sein.

Wenn Sie Ihr Dokument zuerst in SomeObject deserialisieren, erhalten alle Felder ihren Standardwert (null für Strings, 0 für Ints usw.). Und wenn Sie dieses Objekt für die Aktualisierung verwenden, werden die Felder, die in Ihrer JSON-Zeichenfolge nicht vorhanden waren, auf ihren Standardwert aktualisiert.

Wenn Sie

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

Dokuments auf der Datenbank wird nur für die Felder aktualisiert werden, die in Ihrem jsonString vorhanden sind

2

Ich schlage vor, dass Sie sich auf 1.x Legacy API vermeiden verlassen, wie es wird auch in 2.x perfekt unterstützt, wie im folgenden Beispielcode gezeigt.

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 gehen an Robert Stam für die Bereitstellung des Codebeispiels.

Verwandte Themen