/// <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> /// Deletes many to many relation record /// </summary> /// <param name="relationId"></param> /// <param name="originId"></param> /// <param name="targetId"></param> public void DeleteManyToManyRecord(Guid relationId, Guid originId, Guid targetId) { var entityRepository = new MongoEntityRepository(); var relation = Read(relationId); var originEntity = entityRepository.Read(relation.OriginEntityId); var originField = originEntity.Fields.Single(x => x.Id == relation.OriginFieldId); var targetEntity = entityRepository.Read(relation.TargetEntityId); var targetField = targetEntity.Fields.Single(x => x.Id == relation.TargetFieldId); var originColletion = MongoStaticContext.Context.GetBsonCollection("rec_" + originEntity.Name); var originFieldName = originField.Name; if (originFieldName == "id") { originFieldName = "_id"; } var originRecords = originColletion.Find(Query.EQ(originFieldName, originId)).ToList(); var originRecordsCount = originRecords.Count(); BsonDocument originRecord = null; if (originRecordsCount == 0) { throw new StorageException("There are no record with specified origin id."); } else if (originRecordsCount > 1) { throw new StorageException("There are more than 1 record with same origin id."); } else { originRecord = originRecords[0]; var targetsElementName = $"#{ relation.Name}_targets"; BsonElement bsonElement = null; try { bsonElement = originRecord.GetElement(targetsElementName); } catch { } if (bsonElement != null) { var targets = BsonTypeMapper.MapToDotNetValue(bsonElement.Value) as List <object>; if (targets != null && targets.Contains(targetId)) { targets.Remove(targetId); if (targets.Count == 0) { targets = null; } originRecord[targetsElementName] = BsonTypeMapper.MapToBsonValue(targets); } } else { originRecord[targetsElementName] = BsonTypeMapper.MapToBsonValue(null); } } var targetColletion = MongoStaticContext.Context.GetBsonCollection("rec_" + targetEntity.Name); var targetFieldName = targetField.Name; if (targetFieldName == "id") { targetFieldName = "_id"; } var targetRecords = targetColletion.Find(Query.EQ(targetFieldName, targetId)).ToList(); var targetRecordsCount = targetRecords.Count(); BsonDocument targetRecord = null; if (targetRecordsCount == 0) { throw new StorageException("There are no record with specified target id."); } else if (targetRecordsCount > 1) { throw new StorageException("There are more than 1 record with same target id."); } else { targetRecord = targetRecords[0]; var originsElementName = $"#{ relation.Name}_origins"; BsonElement bsonElement = null; try { bsonElement = targetRecord.GetElement(originsElementName); } catch { } if (bsonElement != null) { var origins = BsonTypeMapper.MapToDotNetValue(bsonElement.Value) as List <object>; if (origins != null && origins.Contains(originId)) { origins.Remove(originId); if (origins.Count == 0) { origins = null; } targetRecord[originsElementName] = BsonTypeMapper.MapToBsonValue(origins); } } else { targetRecord[originsElementName] = BsonTypeMapper.MapToBsonValue(null); } } MongoTransaction transaction = null; if (!MongoStaticContext.Context.TransactionInProgress) { transaction = MongoStaticContext.Context.CreateTransaction(); } try { originColletion.Save(originRecord); targetColletion.Save(targetRecord); if (transaction != null) { transaction.Commit(); } } catch { if (transaction != null) { transaction.Rollback(); } throw; } }