/// <summary>
        /// Creates entity relation
        /// </summary>
        /// <param name="entity"></param>
        public bool Create(IStorageEntityRelation entityRelation)
        {
            if (entityRelation == null)
            {
                throw new ArgumentNullException("entityRelation");
            }

            var mongoEntityRelation = entityRelation as MongoEntityRelation;

            if (mongoEntityRelation == null)
            {
                throw new Exception("The specified entityRelation is not mongo storage object.");
            }

            MongoTransaction transaction = null;

            if (!MongoStaticContext.Context.TransactionInProgress)
            {
                transaction = MongoStaticContext.Context.CreateTransaction(true, new MongoTransactionOptions {
                    Isolation = MongoTransactionIsolation.ReadUncommitted
                });
            }

            lock (lockObject)
            {
                try
                {
                    cachedRelations = null;
                    var created    = MongoStaticContext.Context.EntityRelations.Create(mongoEntityRelation);
                    var relation   = Read(mongoEntityRelation.Name);
                    var recRepo    = new MongoRecordRepository();
                    var entityRepo = new MongoEntityRepository();

                    var originEntity = entityRepo.Read(relation.OriginEntityId);
                    var targetEntity = entityRepo.Read(relation.TargetEntityId);

                    recRepo.CreateRecordField(originEntity.Name, $"#{relation.Name}_targets", null);
                    recRepo.CreateRecordField(targetEntity.Name, $"#{relation.Name}_origins", null);

                    InvalidateRelationIndex(relation);

                    if (transaction != null)
                    {
                        transaction.Commit();
                    }

                    cachedRelations = null;
                    return(created);
                }
                catch
                {
                    if (transaction != null)
                    {
                        transaction.Rollback();
                    }

                    throw;
                }
            }
        }
        /// <summary>
        /// Deletes entity relation
        /// </summary>
        /// <param name="id"></param>
        /// <returns></returns>
        public bool Delete(Guid id)
        {
            lock (lockObject)
            {
                MongoTransaction transaction = null;
                if (!MongoStaticContext.Context.TransactionInProgress)
                {
                    transaction = MongoStaticContext.Context.CreateTransaction();
                }

                try
                {
                    var relation = Read(id);

                    var recRepo      = new MongoRecordRepository();
                    var entityRepo   = new MongoEntityRepository();
                    var originEntity = entityRepo.Read(relation.OriginEntityId);
                    var targetEntity = entityRepo.Read(relation.TargetEntityId);

                    recRepo.RemoveRecordField(originEntity.Name, $"#{relation.Name}_targets");
                    recRepo.RemoveRecordField(targetEntity.Name, $"#{relation.Name}_origins");

                    InvalidateRelationIndex(relation, dropIndexes: true);

                    var result = MongoStaticContext.Context.EntityRelations.Delete(Query.EQ("_id", id));

                    if (transaction != null)
                    {
                        transaction.Commit();
                    }

                    cachedRelations = null;
                    return(result);
                }
                catch
                {
                    if (transaction != null)
                    {
                        transaction.Rollback();
                    }

                    throw;
                }
            }
        }
		/// <summary>
		/// Creates entity relation
		/// </summary>
		/// <param name="entity"></param>
		public bool Create(IStorageEntityRelation entityRelation)
		{
			if (entityRelation == null)
				throw new ArgumentNullException("entityRelation");

			var mongoEntityRelation = entityRelation as MongoEntityRelation;

			if (mongoEntityRelation == null)
				throw new Exception("The specified entityRelation is not mongo storage object.");

			MongoTransaction transaction = null;
			if (!MongoStaticContext.Context.TransactionInProgress)
				transaction = MongoStaticContext.Context.CreateTransaction( true, new MongoTransactionOptions { Isolation= MongoTransactionIsolation.ReadUncommitted});

			lock (lockObject)
			{
				try
				{
					cachedRelations = null;
					var created = MongoStaticContext.Context.EntityRelations.Create(mongoEntityRelation);
					var relation = Read(mongoEntityRelation.Name);
					var recRepo = new MongoRecordRepository();
					var entityRepo = new MongoEntityRepository();

					var originEntity = entityRepo.Read(relation.OriginEntityId);
					var targetEntity = entityRepo.Read(relation.TargetEntityId);

					recRepo.CreateRecordField(originEntity.Name, $"#{relation.Name}_targets", null);
					recRepo.CreateRecordField(targetEntity.Name, $"#{relation.Name}_origins", null);

					InvalidateRelationIndex(relation);

					if (transaction != null)
                    transaction.Commit();

					cachedRelations = null;
					return created;
				}
				catch
				{
					if (transaction != null)
					transaction.Rollback();

					throw;
				}
			}
		}
		/// <summary>
		/// Deletes entity relation 
		/// </summary>
		/// <param name="id"></param>
		/// <returns></returns>
		public bool Delete(Guid id)
		{
			lock (lockObject)
			{
				MongoTransaction transaction = null;
				if(!MongoStaticContext.Context.TransactionInProgress)
					transaction = MongoStaticContext.Context.CreateTransaction();

				try
				{
					var relation = Read(id);

					var recRepo = new MongoRecordRepository();
					var entityRepo = new MongoEntityRepository();
					var originEntity = entityRepo.Read(relation.OriginEntityId);
					var targetEntity = entityRepo.Read(relation.TargetEntityId);

					recRepo.RemoveRecordField(originEntity.Name, $"#{relation.Name}_targets");
					recRepo.RemoveRecordField(targetEntity.Name, $"#{relation.Name}_origins");

					InvalidateRelationIndex(relation, dropIndexes: true);

					var result = MongoStaticContext.Context.EntityRelations.Delete(Query.EQ("_id", id));

					if (transaction != null)
					transaction.Commit();

					cachedRelations = null;
					return result;
				}
				catch
				{
					if (transaction != null)
					transaction.Rollback();

					throw;
				}
			}
		}