Example #1
0
        private void InternalUpdate <T>(T entity, string name, ConcurrentSaveOptions saveOptions)        // where T : IMongoEntity
        {
            var mongoEntity = (IMongoEntity)entity;

            MongoCollection <T> coll = Db.GetCollection <T>(name);

            IMongoQuery find;

            if (saveOptions == ConcurrentSaveOptions.ProtectServerChanges)
            {
                find = Query.And(Query.EQ("_id", mongoEntity._id), Query.EQ("_accessId", mongoEntity._accessId));
            }
            else
            {
                find = Query.EQ("_id", mongoEntity._id);
            }

            string originalAccessId = mongoEntity._accessId;

            mongoEntity._accessId = BuildAccessId();

            try
            {
                var wrap               = new BsonDocumentWrapper(entity);
                var update             = new UpdateDocument(wrap.ToBsonDocument());
                WriteConcernResult res = coll.Update(find, update);

                if (res.DocumentsAffected == 1 && res.Ok)
                {
                    // success
                    return;
                }

                if (!res.Ok)
                {
                    throw new MongoConcurrencyException(res.ErrorMessage);
                }

                // problem. is there just no document or is there a concurrency problem.
                // let's do a little work to no be overly agressive on the errors.

                bool isConcurrencyError = coll.Find(Query.EQ("_id", mongoEntity._id)).Any();
                //coll.AsQueryable().Any(e => e._id == mongoEntity._id);
                if (isConcurrencyError)
                {
                    throw new MongoConcurrencyException("Entity modified by other writer since being retreived from db: id = " +
                                                        mongoEntity._id);
                }
                throw new MongoException("Cannot update entity (no entity with ID " + mongoEntity._id + " exists in the db.");
            }
            catch
            {
                mongoEntity._accessId = originalAccessId;
                throw;
            }
        }
Example #2
0
        public void Save <T>(T entity, string connectionName, ConcurrentSaveOptions saveOptions) where T : class
        {
            if (entity == null)
            {
                throw new ArgumentNullException("entity");
            }

            var mongoEntity = entity as IMongoEntity;

            if (mongoEntity == null)
            {
                throw new InvalidOperationException("Cannot save entity in ConcurrentDataContext. " + typeof(T).Name +
                                                    " does not implemented IMongoEntity.");
            }

            if (mongoEntity._id == ObjectId.Empty)
            {
                InternalInsert(entity, connectionName);
            }
            else
            {
                InternalUpdate(entity, connectionName, saveOptions);
            }
        }
Example #3
0
 /// <summary>
 ///     Save changes to entity back to MongoDB with concurrency protection
 ///     specified by saveOptions. If you want to *overwrite* changes made
 ///     on the server use ConcurrentSaveOptions.OverwriteServerChanges.
 /// </summary>
 /// <typeparam name="T">Type of entity</typeparam>
 /// <param name="entity">The entity to be saved</param>
 /// <param name="saveOptions">
 ///     Enables or disables concurrency projected,
 ///     ConcurrentSaveOptions.ProtectServerChanges is recommended.
 /// </param>
 public void Save <T>(T entity, ConcurrentSaveOptions saveOptions) where T : class
 {
     Save(entity, GetCollectionName <T>(), saveOptions);
 }