示例#1
0
        public List <UpdateDefinition <BsonDocument> > BuildUpdatesForSave(
            UpdateDefinition <BsonDocument> update, TrackableListTracker <T> tracker, params object[] keyValues)
        {
            var keyNamespace = DocumentHelper.ToDotPath(keyValues);

            // Multiple push-back batching optimization
            if (tracker.ChangeList.Count > 1 &&
                tracker.ChangeList.All(c => c.Operation == TrackableListOperation.PushBack))
            {
                var newValues = tracker.ChangeList.Select(c => c.NewValue);
                return(new List <UpdateDefinition <BsonDocument> >
                {
                    update == null
                        ? Builders <BsonDocument> .Update.PushEach(keyNamespace, newValues)
                        : update.PushEach(keyNamespace, newValues)
                });
            }

            // Multiple push-front batching optimization
            if (tracker.ChangeList.Count > 1 &&
                tracker.ChangeList.All(c => c.Operation == TrackableListOperation.PushFront))
            {
                var newValues = tracker.ChangeList.Select(c => c.NewValue).Reverse();
                return(new List <UpdateDefinition <BsonDocument> >
                {
                    update == null
                        ? Builders <BsonDocument> .Update.PushEach(keyNamespace, newValues, position : 0)
                        : update.PushEach(keyNamespace, newValues, position: 0)
                });
            }

            // List update can process only one change each time
            var updates = new List <UpdateDefinition <BsonDocument> >();

            foreach (var change in tracker.ChangeList)
            {
                switch (change.Operation)
                {
                case TrackableListOperation.Insert:
                    updates.Add(update == null
                            ? Builders <BsonDocument> .Update.PushEach(keyNamespace, new[] { change.NewValue }, position: change.Index)
                            : update.PushEach(keyNamespace, new[] { change.NewValue }, position: change.Index));
                    update = null;
                    break;

                case TrackableListOperation.Remove:
                    throw new Exception("Remove operation is not supported!");

                case TrackableListOperation.Modify:
                    updates.Add(update == null
                            ? Builders <BsonDocument> .Update.Set(keyNamespace + "." + change.Index, change.NewValue)
                            : update.Set(keyNamespace + "." + change.Index, change.NewValue));
                    break;

                case TrackableListOperation.PushFront:
                    updates.Add(update == null
                            ? Builders <BsonDocument> .Update.PushEach(keyNamespace, new[] { change.NewValue }, position: 0)
                            : update.PushEach(keyNamespace, new[] { change.NewValue }, position: 0));
                    break;

                case TrackableListOperation.PushBack:
                    updates.Add(update == null
                            ? Builders <BsonDocument> .Update.Push(keyNamespace, change.NewValue)
                            : update.Push(keyNamespace, change.NewValue));
                    break;

                case TrackableListOperation.PopFront:
                    updates.Add(update == null
                            ? Builders <BsonDocument> .Update.PopFirst(keyNamespace)
                            : update.PopFirst(keyNamespace));
                    break;

                case TrackableListOperation.PopBack:
                    updates.Add(update == null
                            ? Builders <BsonDocument> .Update.PopLast(keyNamespace)
                            : update.PopLast(keyNamespace));
                    break;
                }
            }

            if (update != null)
            {
                updates.Add(update);
            }

            return(updates);
        }