/// <summary> /// Creates a new entity in the database from the encoded information. The entity /// is saved before being returned. /// </summary> /// <param name="encodedEntity">The encoded entity information to create the new entity from.</param> /// <returns>A reference to the new entity.</returns> protected IEntity CreateNewEntity(EncodedEntity encodedEntity) { Type entityType = Reflection.FindType(typeof(IEntity), encodedEntity.EntityType); var service = Reflection.GetServiceForEntityType(entityType, RockContext); if (service != null) { var addMethod = service.GetType().GetMethod("Add", new Type[] { entityType }); if (addMethod != null) { IEntity entity = ( IEntity )Activator.CreateInstance(entityType); RestoreEntityProperties(entity, encodedEntity); entity.Guid = FindMappedGuid(encodedEntity.Guid); // // Do custom pre-save processing. // foreach (var processor in FindEntityProcessors(entityType)) { processor.ProcessImportedEntity(entity, encodedEntity, encodedEntity.GetTransformData(processor.Identifier.ToString()), this); } // // Special handling of AttributeQualifier because Guids may not be the same // across installations and the AttributeId+Key columns make up a unique key. // if (encodedEntity.EntityType == "Rock.Model.AttributeQualifier") { var reference = encodedEntity.References.Where(r => r.Property == "AttributeId").First(); var attribute = GetExistingEntity("Rock.Model.Attribute", FindMappedGuid(new Guid(( string )reference.Data))); string key = ( string )encodedEntity.Properties["Key"]; var existingEntity = new AttributeQualifierService(RockContext) .GetByAttributeId(attribute.Id) .Where(a => a.Key == key) .FirstOrDefault(); if (existingEntity != null) { if (entity.Guid != encodedEntity.Guid) { throw new Exception("AttributeQualifier marked for new Guid but conflicting value already exists."); } GuidMap.AddOrReplace(encodedEntity.Guid, existingEntity.Guid); return(existingEntity); } } // // Special handling of Attribute's. The guid's might be different but if the entity type, // entity qualifiers and key are the same, assume it's the same. // else if (encodedEntity.EntityType == "Rock.Model.Attribute") { var attribute = (Rock.Model.Attribute)entity; var existingEntity = new AttributeService(RockContext) .GetByEntityTypeId(attribute.EntityTypeId) .Where(a => a.EntityTypeQualifierColumn == attribute.EntityTypeQualifierColumn && a.EntityTypeQualifierValue == attribute.EntityTypeQualifierValue && a.Key == attribute.Key) .FirstOrDefault(); if (existingEntity != null) { if (entity.Guid != encodedEntity.Guid) { throw new Exception("Attribute marked for new Guid but conflicting value already exists."); } GuidMap.AddOrReplace(encodedEntity.Guid, existingEntity.Guid); return(existingEntity); } } // // Special handling of AttributeValue's. The guid's might be different but if the attribute Id // and entity Id are the same, assume it's the same. // else if (encodedEntity.EntityType == "Rock.Model.AttributeValue") { var attributeReference = encodedEntity.References.Where(r => r.Property == "AttributeId").First(); var attribute = GetExistingEntity("Rock.Model.Attribute", FindMappedGuid(new Guid(( string )attributeReference.Data))); var entityReference = encodedEntity.References.Where(r => r.Property == "EntityId").First(); var entityRef = GetExistingEntity(entityReference.EntityType, FindMappedGuid(new Guid(( string )entityReference.Data))); var existingEntity = new AttributeValueService(RockContext) .Queryable().Where(a => a.AttributeId == attribute.Id && a.EntityId == entityRef.Id) .FirstOrDefault(); if (existingEntity != null) { if (entity.Guid != encodedEntity.Guid) { throw new Exception("AttributeValue marked for new Guid but conflicting value already exists."); } GuidMap.AddOrReplace(encodedEntity.Guid, existingEntity.Guid); return(existingEntity); } } addMethod.Invoke(service, new object[] { entity }); RockContext.SaveChanges(true); return(entity); } } throw new Exception(string.Format("Failed to create new database entity for {0}_{1}", encodedEntity.EntityType, encodedEntity.Guid)); }