public void ConvertNtoNRelations() { List <IStorageEntityRelation> relations = Read(); foreach (var relation in relations) { if (relation.RelationType != Api.Models.EntityRelationType.ManyToMany) { continue; } MongoEntity originEntity = MongoStaticContext.Context.Entities.GetById(relation.OriginEntityId); MongoEntity targetEntity = MongoStaticContext.Context.Entities.GetById(relation.TargetEntityId); IStorageField originField = originEntity.Fields.SingleOrDefault(x => x.Id == relation.OriginFieldId); IStorageField targetField = targetEntity.Fields.SingleOrDefault(x => x.Id == relation.TargetFieldId); string originRelationFieldName = $"#{relation.Name}_origins"; string targetRelationFieldName = $"#{relation.Name}_targets"; var relationEntityRecordCollections = MongoStaticContext.Context.GetBsonCollection(RELATION_COLLECTION_PREFIX + relation.Name); var relationEntityRecords = relationEntityRecordCollections.FindAll().ToList(); if (relationEntityRecords != null && relationEntityRecords.Count() > 0) { var transaction = MongoStaticContext.Context.CreateTransaction(); try { var originEntityRecordCollection = MongoStaticContext.Context.GetBsonCollection(MongoRecordRepository.RECORD_COLLECTION_PREFIX + originEntity.Name); var originEntityRecords = originEntityRecordCollection.FindAll().ToList(); if (originEntityRecords != null && originEntityRecords.Count() > 0) { foreach (var originRecord in originEntityRecords) { string originFieldName = originField.Name == "id" ? $"_id" : originField.Name; List <Guid> targetRecordsToCopy = relationEntityRecords.Where(r => (Guid)r["originId"] == (Guid)originRecord[originFieldName]).Select(r => (Guid)r["targetId"]).ToList(); originRecord[targetRelationFieldName] = targetRecordsToCopy == null || targetRecordsToCopy.Count() == 0 ? BsonNull.Value : BsonValue.Create(targetRecordsToCopy); var updateSuccess = originEntityRecordCollection.Save(originRecord).DocumentsAffected > 0; //if (!updateSuccess) // throw new StorageException("Failed to update record."); } } var targetEntityRecordCollection = MongoStaticContext.Context.GetBsonCollection(MongoRecordRepository.RECORD_COLLECTION_PREFIX + targetEntity.Name); var targetEntityRecords = targetEntityRecordCollection.FindAll().ToList(); if (targetEntityRecords != null && targetEntityRecords.Count() > 0) { foreach (var targetRecord in targetEntityRecords) { string targetFieldName = targetField.Name == "id" ? $"_id" : targetField.Name; List <Guid> originRecordsToCopy = relationEntityRecords.Where(r => (Guid)r["targetId"] == (Guid)targetRecord[targetFieldName]).Select(r => (Guid)r["originId"]).ToList(); targetRecord[originRelationFieldName] = originRecordsToCopy == null || originRecordsToCopy.Count() == 0 ? BsonNull.Value : BsonValue.Create(originRecordsToCopy);; var updateSuccess = targetEntityRecordCollection.Save(targetRecord).DocumentsAffected > 0; //if (!updateSuccess) // throw new StorageException("Failed to update record."); } } transaction.Commit(); IndexOptionsBuilder originOptions = IndexOptions.SetUnique(false).SetDropDups(false).SetName(targetRelationFieldName).SetBackground(true); originEntityRecordCollection.CreateIndex(new IndexKeysBuilder().Ascending(targetRelationFieldName), originOptions); IndexOptionsBuilder targetOptions = IndexOptions.SetUnique(false).SetDropDups(false).SetName(originRelationFieldName).SetBackground(true); targetEntityRecordCollection.CreateIndex(new IndexKeysBuilder().Ascending(originRelationFieldName), targetOptions); } catch (Exception) { transaction.Rollback(); } } } }
private void InvalidateRelationIndex(IStorageEntityRelation entityRelation) { MongoEntity originEntity = MongoStaticContext.Context.Entities.GetById(entityRelation.OriginEntityId); MongoEntity targetEntity = MongoStaticContext.Context.Entities.GetById(entityRelation.TargetEntityId); if (originEntity == null || targetEntity == null) { return; } IStorageField originField = originEntity.Fields.SingleOrDefault(x => x.Id == entityRelation.OriginFieldId); IStorageField targetField = targetEntity.Fields.SingleOrDefault(x => x.Id == entityRelation.TargetFieldId); if (originField == null || targetField == null) { return; } if (entityRelation.RelationType != Api.Models.EntityRelationType.ManyToMany) { var originCollection = MongoStaticContext.Context.GetBsonCollection(MongoRecordRepository.RECORD_COLLECTION_PREFIX + originEntity.Name); if (originCollection == null) { return; } if (originField.Name != "id") { var originIndexes = originCollection.GetIndexes(); var originIndexName = "relation_" + entityRelation.Id + "_" + originField.Name; var originIndex = originIndexes.SingleOrDefault(x => x.Name == originIndexName); if (originIndex != null) { originCollection.DropIndexByName(originIndexName); } IndexOptionsBuilder options = IndexOptions.SetUnique(false).SetDropDups(false).SetName(originIndexName).SetBackground(true); originCollection.CreateIndex(new IndexKeysBuilder().Ascending(originField.Name), options); } var targetCollection = MongoStaticContext.Context.GetBsonCollection(MongoRecordRepository.RECORD_COLLECTION_PREFIX + targetEntity.Name); if (targetEntity == null) { return; } if (targetField.Name != "id") { var targetIndexes = targetCollection.GetIndexes(); var targetIndexName = "relation_" + entityRelation.Id + "_" + targetField.Name; var targetIndex = targetIndexes.SingleOrDefault(x => x.Name == targetIndexName); if (targetIndex != null) { targetCollection.DropIndexByName(targetIndexName); } IndexOptionsBuilder options = IndexOptions.SetUnique(false).SetDropDups(false).SetName(targetIndexName).SetBackground(true); targetCollection.CreateIndex(new IndexKeysBuilder().Ascending(targetField.Name), options); } } else { var collection = MongoStaticContext.Context.GetBsonCollection(RELATION_COLLECTION_PREFIX + entityRelation.Name); var indexes = collection.GetIndexes(); var originIndexName = "relation_origin"; var originIndex = indexes.SingleOrDefault(x => x.Name == originIndexName); if (originIndex != null) { collection.DropIndexByName(originIndexName); } IndexOptionsBuilder options = IndexOptions.SetUnique(false).SetDropDups(false).SetName(originIndexName).SetBackground(true); collection.CreateIndex(new IndexKeysBuilder().Ascending("relationId").Ascending("originId"), options); var targetIndexName = "relation_target"; var targetIndex = indexes.SingleOrDefault(x => x.Name == targetIndexName); if (targetIndex != null) { collection.DropIndexByName(targetIndexName); } options = IndexOptions.SetUnique(false).SetDropDups(false).SetName(targetIndexName).SetBackground(true); collection.CreateIndex(new IndexKeysBuilder().Ascending("relationId").Ascending("targetId"), options); } }