/// <summary> /// Converts an association type from SOM to metadata /// </summary> /// <param name="element">The SOM element to process</param> /// <param name="providerManifest">The provider manifest to be used for conversion</param> /// <param name="convertedItemCache">The item collection for currently existing metadata objects</param> /// <param name="newGlobalItems">The new GlobalItem objects that are created as a result of this conversion</param> /// <returns>The association type object resulting from the convert</returns> private static AssociationType ConvertToAssociationType(Som.Relationship element, DbProviderManifest providerManifest, ConversionCache convertedItemCache, Dictionary<Som.SchemaElement, GlobalItem> newGlobalItems) { Debug.Assert(element.RelationshipKind == RelationshipKind.Association); AssociationType associationType = new AssociationType(element.Name, element.Namespace, element.IsForeignKey, GetDataSpace(providerManifest)); newGlobalItems.Add(element, associationType); foreach (Som.RelationshipEnd end in element.Ends) { Som.SchemaType entityTypeElement = end.Type; EntityType endEntityType = (EntityType)LoadSchemaElement(entityTypeElement, providerManifest, convertedItemCache, newGlobalItems); AssociationEndMember endMember = InitializeAssociationEndMember(associationType, end, endEntityType); AddOtherContent(end, endMember); // Loop through and convert the operations foreach (Som.OnOperation operation in end.Operations) { // Process only the ones that we recognize if (operation.Operation != Som.Operation.Delete) { continue; } // Determine the action for this operation OperationAction action = OperationAction.None; switch (operation.Action) { case Som.Action.Cascade: action = OperationAction.Cascade; break; case Som.Action.None: action = OperationAction.None; break; default: Debug.Fail("Operation action not supported."); break; } endMember.DeleteBehavior = action; } // Extract optional Documentation from the end element if (end.Documentation != null) { endMember.Documentation = ConvertToDocumentation(end.Documentation); } } Debug.Assert(associationType.ReferentialConstraints.Count == 0, "This must never have been initialized"); for (int i = 0; i < element.Constraints.Count; i++) { Som.ReferentialConstraint constraint = element.Constraints[i]; AssociationEndMember fromMember = (AssociationEndMember)associationType.Members[constraint.PrincipalRole.Name]; AssociationEndMember toMember = (AssociationEndMember)associationType.Members[constraint.DependentRole.Name]; EntityTypeBase fromEntityType = ((RefType)fromMember.TypeUsage.EdmType).ElementType; EntityTypeBase toEntityType = ((RefType)toMember.TypeUsage.EdmType).ElementType; ReferentialConstraint referentialConstraint = new ReferentialConstraint(fromMember, toMember, GetProperties(fromEntityType, constraint.PrincipalRole.RoleProperties), GetProperties(toEntityType, constraint.DependentRole.RoleProperties)); // Attach the optional Documentation if (constraint.Documentation != null) referentialConstraint.Documentation = ConvertToDocumentation(constraint.Documentation); if (constraint.PrincipalRole.Documentation != null) referentialConstraint.FromRole.Documentation = ConvertToDocumentation(constraint.PrincipalRole.Documentation); if (constraint.DependentRole.Documentation != null) referentialConstraint.ToRole.Documentation = ConvertToDocumentation(constraint.DependentRole.Documentation); associationType.AddReferentialConstraint(referentialConstraint); AddOtherContent(element.Constraints[i], referentialConstraint); } // Extract the optional Documentation if (element.Documentation != null) { associationType.Documentation = ConvertToDocumentation(element.Documentation); } AddOtherContent(element, associationType); return associationType; }
private AssociationType CreateModelAssociationType(LoadMethodSessionState session, AssociationType storeAssociationType) { UniqueIdentifierService usedEndMemberNames = new UniqueIdentifierService(false); string name = CreateModelName(storeAssociationType.Name, session.UsedGlobalModelTypeNames); bool isFkAssociation = false; if (_targetEntityFrameworkVersion > EntityFrameworkVersions.Version1) { isFkAssociation = this.GenerateForeignKeyProperties || RequiresModelReferentialConstraint(storeAssociationType); } AssociationType association = new AssociationType(name, _namespaceName, isFkAssociation, DataSpace.CSpace); KeyValuePair<string, RelationshipMultiplicity> endMultiplicityOverride = CreateEndMultiplicityOverride(session, storeAssociationType, association); foreach (AssociationEndMember storeEndMember in storeAssociationType.RelationshipEndMembers) { AssociationEndMember end = CreateAssociationEndMember(session, storeEndMember, endMultiplicityOverride, usedEndMemberNames); session.MappingLookups.StoreAssociationEndMemberToModelAssociationEndMember.Add(storeEndMember, end); association.AddMember(end); } ReferentialConstraint constraint = CreateReferentialConstraint(session, storeAssociationType); if (constraint != null) { association.AddReferentialConstraint(constraint); } CreateModelNavigationProperties(session, association); return association; }
private bool CreateReferentialConstraint(LoadMethodSessionState session, AssociationType association, AssociationEndMember pkEnd, AssociationEndMember fkEnd, List<RelationshipDetailsRow> columns, List<EdmSchemaError> errors) { EdmProperty[] fromProperties = new EdmProperty[columns.Count]; EdmProperty[] toProperties = new EdmProperty[columns.Count]; EntityType pkEntityType = session.RelationshipEndTypeLookup[pkEnd]; EntityType fkEntityType = session.RelationshipEndTypeLookup[fkEnd]; for (int index = 0; index < columns.Count; index++) { EdmProperty property; if(!pkEntityType.Properties.TryGetValue(columns[index].PKColumn, false, out property)) { errors.Add( new EdmSchemaError( Strings.AssociationMissingKeyColumn( pkEntityType.Name, fkEntityType.Name, pkEntityType.Name + "." + columns[index].PKColumn), (int)ModelBuilderErrorCode.AssociationMissingKeyColumn, EdmSchemaErrorSeverity.Warning)); return false; } fromProperties[index] = property; if(!fkEntityType.Properties.TryGetValue(columns[index].FKColumn, false, out property)) { errors.Add( new EdmSchemaError( Strings.AssociationMissingKeyColumn( pkEntityType.Name, fkEntityType.Name, fkEntityType.Name + "." + columns[index].FKColumn), (int)ModelBuilderErrorCode.AssociationMissingKeyColumn, EdmSchemaErrorSeverity.Warning)); return false; } toProperties[index] = property; } ReferentialConstraint constraint = new ReferentialConstraint(pkEnd, fkEnd, fromProperties, toProperties); association.AddReferentialConstraint(constraint); return true; }