Weet niet precies wat je wilt. Er zijn in wezen twee soorten updates in MongoDB:u kunt een atomic update uitvoeren , of vervang het document .
Het document vervangen is vaak makkelijker , omdat het je in staat stelt om standaard C#-bewerkingen te gebruiken om wijzigingen uit te voeren en het zal gegenereerde eigenschappen en dergelijke opnieuw evalueren:
var user = new User { Name = "John Doe", Quests =
new Dictionary<string, Tuple<string, string>> {
{ "hoho", new Tuple<string, string>("A", "A-Item") } } };
users.InsertOneAsync(user).Wait();
user.Quests = new Dictionary<string, Tuple<string, string>> {
{ "hoho Modified", new Tuple<string, string>("B", "B-Item") } };
users.ReplaceOneAsync(p => p.Id == user.Id, user);
Soms is het echter vereist om atomaire modifiers te gebruiken, zoals $push
, $pull
, $set
, $addToSet
, enz. vanwege zorgen over gelijktijdigheid. Ik beschouw het over het algemeen als een slecht idee om op deze manier complexe bewerkingen uit te voeren op complexe ingebedde objecten, omdat de kans groot is dat de consistentie van het object (in de ACID-zin, of 'objectinvarianten' ) kan niet worden gecontroleerd.
Stel dat een gebruiker niet meer dan 3 actieve missies tegelijk mag hebben, wie zorgt ervoor dat deze regel wordt nageleefd? Dat is normaal gesproken de verantwoordelijkheid van de code, en complexe invarianten kunnen niet worden gecontroleerd door de database.
Als je die atomaire operatoren nog steeds wilt gebruiken, raad ik je aan een nieuwe vraag te stellen, want daar hangt het echt af van de details (het woordenboek is standaard geserialiseerd als een document, de tuple als een array, en ze vereisen verschillende atomaire modifiers in MongoDB). Om bijvoorbeeld een nieuw item aan het woordenboek toe te voegen, gebruikt u $set
:
users.UpdateOneAsync(p => p.Id == user.Id,
Builders<User>.Update.Set("Quests.hoho Modified",
new Tuple<string, string>("B", "B-Item")));