Пример #1
0
        /// <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;
        }