private static UpdateDefinition <TEntity> CreateFromDiff <TEntity>(UpdateDefinition <TEntity> definition, string name, BsonDocument documentA, BsonDocument documentB) where TEntity : class { var documentAProperties = documentA?.Names ?? Enumerable.Empty <string>(); var documentBProperties = documentB?.Names ?? Enumerable.Empty <string>(); var propertyNames = documentAProperties.Union(documentBProperties); if (name != string.Empty) { name += "."; } foreach (var propertyName in propertyNames) { var fullName = name + propertyName; if (documentB == null || !documentB.Contains(propertyName)) { definition = definition.Unset(new StringFieldDefinition <TEntity>(fullName)); } else if (documentA == null || !documentA.Contains(propertyName)) { definition = definition.Set(fullName, documentB[propertyName]); } else { definition = CreateFromDiff(definition, fullName, documentA[propertyName], documentB[propertyName]); } } return(definition); }
public UpdateDefinition <BsonDocument> BuildUpdatesForSave(UpdateDefinition <BsonDocument> update, TrackableDictionaryTracker <TKey, TValue> tracker, params object[] keyValues) { var keyNamespace = DocumentHelper.ToDotPathWithTrailer(keyValues); foreach (var change in tracker.ChangeMap) { switch (change.Value.Operation) { case TrackableDictionaryOperation.Add: case TrackableDictionaryOperation.Modify: update = update == null ? Builders <BsonDocument> .Update.Set(keyNamespace + change.Key, change.Value.NewValue) : update.Set(keyNamespace + change.Key, change.Value.NewValue); break; case TrackableDictionaryOperation.Remove: update = update == null ? Builders <BsonDocument> .Update.Unset(keyNamespace + change.Key) : update.Unset(keyNamespace + change.Key); break; } } return(update); }
public UpdateDefinition <BsonDocument> BuildUpdatesForSave( UpdateDefinition <BsonDocument> update, TrackablePocoTracker <T> tracker, params object[] keyValues) { var keyNamespace = DocumentHelper.ToDotPathWithTrailer(keyValues); // mimic BsonClassMapSerializer.Serialize to serialize changed value correctly. // build bson elements containing set field values var setDocument = new BsonDocument(); var setBsonWriter = new BsonDocumentWriter(setDocument); var setContext = BsonSerializationContext.CreateRoot(setBsonWriter); setBsonWriter.WriteStartDocument(); foreach (var change in tracker.ChangeMap) { if (change.Value.NewValue != null) { BsonMemberMap memberMap; if (_propertyToMemberMap.TryGetValue(change.Key, out memberMap) == false) { continue; } setBsonWriter.WriteName(memberMap.ElementName); memberMap.GetSerializer().Serialize(setContext, change.Value.NewValue); } else { update = (update == null) ? Builders <BsonDocument> .Update.Unset(keyNamespace + change.Key.Name) : update.Unset(keyNamespace + change.Key.Name); } } setBsonWriter.WriteEndDocument(); setBsonWriter.Dispose(); foreach (var element in setDocument.Elements) { update = (update == null) ? Builders <BsonDocument> .Update.Set(keyNamespace + element.Name, element.Value) : update.Set(keyNamespace + element.Name, element.Value); } return(update); }
public bool Reset <T>(IMongoCollection <T> collection, params string[] vs) { if (vs == null) { throw new ArgumentNullException(nameof(vs)); } FilterDefinition <T> filter = Builders <T> .Filter.Eq("_id", Id); string name; PropertyInfo propety; UpdateDefinitionBuilder <T> update = Builders <T> .Update; UpdateDefinition <T> updateDefinition = null; for (int i = 0; i < vs.Length; i++) { name = vs[i]; propety = typeof(T).GetProperty(name); if (propety == null) { return(false); } if (updateDefinition == null) { updateDefinition = update.Unset(name); } else { updateDefinition = updateDefinition.Unset(name); } } collection.UpdateOne(filter, updateDefinition); return(true); }