public static void TryGetAdjustedName_correctly_retrieves_the_adjusted_identifier_associated_with_an_object()
        {
            const string identifier = "Identifier";
            const string adjustedIdentifier1 = "Identifier1";
            const string adjustedIdentifier2 = "Identifier2";
            const string adjustedIdentifier3 = "Identifier3";
            string adjustedIdentifier;

            var value1 = new object();
            var value2 = new object();
            var value3 = new object();

            var service = new UniqueIdentifierService();
            service.RegisterUsedIdentifier(identifier);

            Assert.Equal(adjustedIdentifier1, service.AdjustIdentifier(identifier, value1));
            Assert.Equal(adjustedIdentifier2, service.AdjustIdentifier(identifier, value2));
            Assert.Equal(adjustedIdentifier3, service.AdjustIdentifier(identifier, value3));
            Assert.True(service.TryGetAdjustedName(value1, out adjustedIdentifier));
            Assert.Equal(adjustedIdentifier, adjustedIdentifier1);
            Assert.True(service.TryGetAdjustedName(value2, out adjustedIdentifier));
            Assert.Equal(adjustedIdentifier, adjustedIdentifier2);
            Assert.True(service.TryGetAdjustedName(value3, out adjustedIdentifier));
            Assert.Equal(adjustedIdentifier, adjustedIdentifier3);
        }
        public static void RegisterUsedIdentifier_uses_the_specified_StringComparer_correctly()
        {
            const string identifierA = "Identifier";
            const string identifierB = "IdeNTiFieR";

            var service = new UniqueIdentifierService(StringComparer.Ordinal);
            service.RegisterUsedIdentifier(identifierA);
            Assert.DoesNotThrow(() => service.RegisterUsedIdentifier(identifierB));

            service = new UniqueIdentifierService(StringComparer.OrdinalIgnoreCase);
            service.RegisterUsedIdentifier(identifierA);
            Assert.Throws<ArgumentException>(() => service.RegisterUsedIdentifier(identifierB));
        }
        public static void AdjustIdentifier_with_Ordinal_comparer_and_identity_transform_returns_expected_result()
        {
            const string identifier = "Identifier";
            const string adjustedIdentifier1 = "Identifier1";
            const string adjustedIdentifier2 = "Identifier2";
            const string adjustedIdentifier3 = "Identifier3";

            var service = new UniqueIdentifierService(StringComparer.Ordinal);
            service.RegisterUsedIdentifier(identifier);

            Assert.Equal(adjustedIdentifier1, service.AdjustIdentifier(identifier));
            Assert.Equal(adjustedIdentifier2, service.AdjustIdentifier(identifier));
            Assert.Equal(adjustedIdentifier3, service.AdjustIdentifier(identifier));
        }
        public static void AdjustIdentifier_with_OrdinalIgnoreCase_comparer_and_custom_transform_returns_expected_result()
        {
            const string identifier = "My.Identifier";
            const string usedIdentifier = "My_IdENtIfiEr";
            const string adjustedIdentifier1 = "My_Identifier1";
            const string adjustedIdentifier2 = "My_Identifier2";
            const string adjustedIdentifier3 = "My_Identifier3";

            Func<string, string> transform = s => s.Replace(".", "_");

            var service = new UniqueIdentifierService(StringComparer.OrdinalIgnoreCase, transform);
            service.RegisterUsedIdentifier(usedIdentifier);

            Assert.Equal(adjustedIdentifier1, service.AdjustIdentifier(identifier));
            Assert.Equal(adjustedIdentifier2, service.AdjustIdentifier(identifier));
            Assert.Equal(adjustedIdentifier3, service.AdjustIdentifier(identifier));
        }
示例#5
0
        // internal for testing
        internal void GenerateEntitySet(
            SimpleMappingContext mappingContext,
            EntitySet storeEntitySet,
            UniqueIdentifierService uniqueEntityContainerNames,
            UniqueIdentifierService globallyUniqueTypeNames)
        {
            Debug.Assert(mappingContext != null, "mappingContext != null");
            Debug.Assert(storeEntitySet != null, "storeEntitySet != null");
            Debug.Assert(uniqueEntityContainerNames != null, "uniqueEntityContainerNames != null");
            Debug.Assert(globallyUniqueTypeNames != null, "globallyUniqueTypeNames != null");

            var conceptualEntityType = GenerateEntityType(mappingContext, storeEntitySet.ElementType, globallyUniqueTypeNames);

            var conceptualEntitySetName = CreateModelName(
                (_pluralizationService != null) ? _pluralizationService.Pluralize(storeEntitySet.Name) : storeEntitySet.Name,
                uniqueEntityContainerNames);

            var conceptualEntitySet = EntitySet.Create(conceptualEntitySetName, null, null, null, conceptualEntityType, null);

            mappingContext.AddMapping(storeEntitySet, conceptualEntitySet);
        }
        // internal for testing
        internal void GenerateEntitySet(
            SimpleMappingContext mappingContext,
            EntitySet storeEntitySet,
            UniqueIdentifierService uniqueEntityContainerNames,
            UniqueIdentifierService globallyUniqueTypeNames)
        {
            Debug.Assert(mappingContext != null, "mappingContext != null");
            Debug.Assert(storeEntitySet != null, "storeEntitySet != null");
            Debug.Assert(uniqueEntityContainerNames != null, "uniqueEntityContainerNames != null");
            Debug.Assert(globallyUniqueTypeNames != null, "globallyUniqueTypeNames != null");

            var conceptualEntityType = GenerateEntityType(mappingContext, storeEntitySet.ElementType, globallyUniqueTypeNames);

            var conceptualEntitySetName = CreateModelName(
                (_pluralizationService != null) ? _pluralizationService.Pluralize(storeEntitySet.Name) : storeEntitySet.Name,
                uniqueEntityContainerNames);

            var conceptualEntitySet = EntitySet.Create(conceptualEntitySetName, null, null, null, conceptualEntityType, null);

            mappingContext.AddMapping(storeEntitySet, conceptualEntitySet);
        }
示例#7
0
        private static AssociationEndMember GenerateAssociationEndMember(
            SimpleMappingContext mappingContext,
            AssociationEndMember storeEndMember,
            UniqueIdentifierService uniqueEndMemberNames,
            RelationshipMultiplicity multiplicity,
            OperationAction deleteBehavior)
        {
            var storeEntityType      = ((EntityType)((RefType)storeEndMember.TypeUsage.EdmType).ElementType);
            var conceptualEntityType = mappingContext[storeEntityType];

            var conceptualEndMember = AssociationEndMember.Create(
                CreateModelName(storeEndMember.Name, uniqueEndMemberNames),
                conceptualEntityType.GetReferenceType(),
                multiplicity,
                deleteBehavior,
                null);

            mappingContext.AddMapping(storeEndMember, conceptualEndMember);

            return(conceptualEndMember);
        }
示例#8
0
        public SimpleMappingContext Build(EdmModel storeModel)
        {
            Debug.Assert(storeModel != null, "storeModel != null");

            var mappingContext = new SimpleMappingContext(storeModel, _generateForeignKeyProperties);

            var uniqueEntityContainerNames = new UniqueIdentifierService();
            var globallyUniqueTypeNames    = new UniqueIdentifierService();

            CollectForeignKeyProperties(mappingContext, storeModel);

            foreach (var storeEntitySet in storeModel.Containers.Single().EntitySets)
            {
                GenerateEntitySet(mappingContext, storeEntitySet, uniqueEntityContainerNames, globallyUniqueTypeNames);
            }

            GenerateAssociationSets(
                mappingContext,
                uniqueEntityContainerNames,
                globallyUniqueTypeNames);

            var functionImports =
                GenerateFunctions(mappingContext, storeModel, uniqueEntityContainerNames, globallyUniqueTypeNames)
                .ToArray();

            var conceptualModelContainer = EntityContainer.Create(
                _containerName,
                DataSpace.CSpace,
                mappingContext.ConceptualEntitySets()
                .Concat(mappingContext.ConceptualAssociationSets().Cast <EntitySetBase>()),
                functionImports,
                EntityFrameworkVersion.DoubleToVersion(storeModel.SchemaVersion) >= EntityFrameworkVersion.Version2
                    ? new[] { CreateAnnotationMetadataProperty("LazyLoadingEnabled", "true") }
                    : null);

            mappingContext.AddMapping(storeModel.Containers.Single(), conceptualModelContainer);

            return(mappingContext);
        }
示例#9
0
        // internal for testing
        internal static FunctionParameter[] CreateFunctionImportParameters(SimpleMappingContext mappingContext, EdmFunction storeFunction)
        {
            Debug.Assert(mappingContext != null, "mappingContext != null");
            Debug.Assert(storeFunction != null, "storeFunctionParameters != null");

            var functionImportParameters = new FunctionParameter[storeFunction.Parameters.Count];

            var uniqueParameterNames = new UniqueIdentifierService();

            for (var idx = 0; idx < storeFunction.Parameters.Count; idx++)
            {
                Debug.Assert(storeFunction.Parameters[idx].Mode == ParameterMode.In, "Only In parameters are supported.");

                var parameterName = CreateModelName(storeFunction.Parameters[idx].Name, uniqueParameterNames);

                if (parameterName != storeFunction.Parameters[idx].Name)
                {
                    mappingContext.Errors.Add(
                        new EdmSchemaError(
                            string.Format(
                                CultureInfo.InvariantCulture,
                                Resources_VersioningFacade.UnableToGenerateFunctionImportParameterName,
                                storeFunction.Parameters[idx].Name,
                                storeFunction.Name),
                            (int)ModelBuilderErrorCode.UnableToGenerateFunctionImportParameterName,
                            EdmSchemaErrorSeverity.Warning));
                    return(null);
                }

                functionImportParameters[idx] =
                    FunctionParameter.Create(
                        parameterName,
                        storeFunction.Parameters[idx].TypeUsage.ModelTypeUsage.EdmType,
                        storeFunction.Parameters[idx].Mode);
            }

            return(functionImportParameters);
        }
        public SimpleMappingContext Build(EdmModel storeModel)
        {
            Debug.Assert(storeModel != null, "storeModel != null");

            var mappingContext = new SimpleMappingContext(storeModel, _generateForeignKeyProperties);

            var uniqueEntityContainerNames = new UniqueIdentifierService();
            var globallyUniqueTypeNames = new UniqueIdentifierService();
            CollectForeignKeyProperties(mappingContext, storeModel);

            foreach (var storeEntitySet in storeModel.Containers.Single().EntitySets)
            {
                GenerateEntitySet(mappingContext, storeEntitySet, uniqueEntityContainerNames, globallyUniqueTypeNames);
            }

            GenerateAssociationSets(
                mappingContext,
                uniqueEntityContainerNames,
                globallyUniqueTypeNames);

            var functionImports =
                GenerateFunctions(mappingContext, storeModel, uniqueEntityContainerNames, globallyUniqueTypeNames)
                    .ToArray();

            var conceptualModelContainer = EntityContainer.Create(
                _containerName,
                DataSpace.CSpace,
                mappingContext.ConceptualEntitySets()
                    .Concat(mappingContext.ConceptualAssociationSets().Cast<EntitySetBase>()),
                functionImports,
                EntityFrameworkVersion.DoubleToVersion(storeModel.SchemaVersion) >= EntityFrameworkVersion.Version2
                    ? new[] { CreateAnnotationMetadataProperty("LazyLoadingEnabled", "true") }
                    : null);

            mappingContext.AddMapping(storeModel.Containers.Single(), conceptualModelContainer);

            return mappingContext;
        }
            public void GenerateFunction_returns_function_with_unique_return_type_name()
            {
                var storeReturnType = CreateRowType(CreateProperty("foo", PrimitiveTypeKind.Int32)).GetCollectionType();
                var returnParameter =
                    FunctionParameter.Create("ReturnType", storeReturnType, ParameterMode.ReturnValue);

                var storeFunction =
                    EdmFunction.Create(
                        "foo*",
                        "bar",
                        DataSpace.SSpace,
                        new EdmFunctionPayload { ReturnParameters = new[] { returnParameter } },
                        null);

                var uniqueContainerNames = new UniqueIdentifierService();
                uniqueContainerNames.AdjustIdentifier("foo_");

                var globallyUniqueTypeNames = new UniqueIdentifierService();
                globallyUniqueTypeNames.AdjustIdentifier("foo_1_Result");

                var mappingContext = new SimpleMappingContext(new EdmModel(DataSpace.SSpace), true);
                var functionImport =
                    CreateOneToOneMappingBuilder()
                        .GenerateFunction(mappingContext, storeFunction, uniqueContainerNames, globallyUniqueTypeNames);

                Assert.NotNull(functionImport);
                Assert.Equal(
                    "myModel.foo_1_Result1",
                    ((CollectionType)functionImport.ReturnParameter.TypeUsage.EdmType).TypeUsage.EdmType.FullName);
                Assert.Empty(mappingContext.Errors);
            }
            public void GenerateScalarProperty_converts_and_uniquifies_property_names()
            {
                var uniquePropertyNameService = new UniqueIdentifierService();
                uniquePropertyNameService.AdjustIdentifier("p_1");

                var storeProperty = EdmProperty.CreatePrimitive("p*1", GetStoreEdmType("int"));

                var conceptualProperty =
                    OneToOneMappingBuilder
                        .GenerateScalarProperty(
                            new SimpleMappingContext(new EdmModel(DataSpace.SSpace), true),
                            storeProperty,
                            uniquePropertyNameService);

                Assert.Equal("p_11", conceptualProperty.Name);
            }
            public void GenerateEntityType_entity_type_name_is_sanitized_and_uniquified()
            {
                var storeEntityType =
                    EntityType.Create(
                        "foo$", "bar", DataSpace.SSpace, new[] { "Id" },
                        new[] { EdmProperty.CreatePrimitive("Id", GetStoreEdmType("int")) }, null);

                var uniqueEntityTypeName = new UniqueIdentifierService();
                uniqueEntityTypeName.AdjustIdentifier("foo_");
                var conceptualEntityType =
                    CreateOneToOneMappingBuilder()
                        .GenerateEntityType(
                            new SimpleMappingContext(new EdmModel(DataSpace.SSpace), true),
                            storeEntityType,
                            uniqueEntityTypeName);

                Assert.Equal("foo_1", conceptualEntityType.Name);
            }
            public void GenerateEntitySet_entity_set_name_sanitized_and_uniquified()
            {
                var storeEntityType =
                    EntityType.Create(
                        "foo", "bar", DataSpace.SSpace, new[] { "Id" },
                        new[] { EdmProperty.CreatePrimitive("Id", GetStoreEdmType("int")) }, null);

                var storeEntitySet = EntitySet.Create("foo$", "bar", null, null, storeEntityType, null);

                var uniqueEntityContainerNames = new UniqueIdentifierService();
                uniqueEntityContainerNames.AdjustIdentifier("foo_");

                var mappingContext = new SimpleMappingContext(new EdmModel(DataSpace.SSpace), true);

                CreateOneToOneMappingBuilder()
                    .GenerateEntitySet(
                        mappingContext,
                        storeEntitySet,
                        uniqueEntityContainerNames,
                        new UniqueIdentifierService());

                var conceptualModelEntitySet = mappingContext[storeEntitySet];

                Assert.Equal("foo_1", conceptualModelEntitySet.Name);
                Assert.Equal("foo", conceptualModelEntitySet.ElementType.Name);
            }
        internal void GenerateAssociationSets(
            SimpleMappingContext mappingContext,
            UniqueIdentifierService uniqueEntityContainerNames,
            UniqueIdentifierService globallyUniqueTypeNames)
        {
            IEnumerable<AssociationSet> associationSetsFromNonCollapsibleItems;

            var collapsibleItems = CollapsibleEntityAssociationSets.CreateCollapsibleItems(
                mappingContext.StoreModel.Containers.Single().BaseEntitySets,
                out associationSetsFromNonCollapsibleItems);

            foreach (var set in associationSetsFromNonCollapsibleItems)
            {
                GenerateAssociationSet(
                    mappingContext,
                    set,
                    uniqueEntityContainerNames,
                    globallyUniqueTypeNames);
            }

            foreach (var item in collapsibleItems)
            {
                GenerateAssociationSet(
                    mappingContext,
                    item,
                    uniqueEntityContainerNames,
                    globallyUniqueTypeNames);
            }
        }
        private static AssociationEndMember GenerateAssociationEndMember(
            SimpleMappingContext mappingContext,
            AssociationEndMember storeEndMember,
            UniqueIdentifierService uniqueEndMemberNames,
            RelationshipMultiplicity multiplicity,
            OperationAction deleteBehavior)
        {
            var storeEntityType = ((EntityType)((RefType)storeEndMember.TypeUsage.EdmType).ElementType);
            var conceptualEntityType = mappingContext[storeEntityType];

            var conceptualEndMember = AssociationEndMember.Create(
                CreateModelName(storeEndMember.Name, uniqueEndMemberNames),
                conceptualEntityType.GetReferenceType(),
                multiplicity,
                deleteBehavior,
                null);

            mappingContext.AddMapping(storeEndMember, conceptualEndMember);

            return conceptualEndMember;
        }
        private void GenerateAssociationSet(
            SimpleMappingContext mappingContext,
            CollapsibleEntityAssociationSets collapsibleItem,
            UniqueIdentifierService uniqueEntityContainerNames,
            UniqueIdentifierService globallyUniqueTypeNames)
        {
            var uniqueEndMemberNames = new UniqueIdentifierService(StringComparer.OrdinalIgnoreCase);

            var associationSetEndDetails0 = collapsibleItem.GetStoreAssociationSetEnd(0);

            var associationEndMember0 = GenerateAssociationEndMember(
                mappingContext,
                associationSetEndDetails0.AssociationSetEnd.CorrespondingAssociationEndMember,
                uniqueEndMemberNames,
                associationSetEndDetails0.Multiplicity,
                associationSetEndDetails0.DeleteBehavior);
            var conceptualEntitySet0 = mappingContext[associationSetEndDetails0.AssociationSetEnd.EntitySet];

            var associationSetEndDetails1 =
                collapsibleItem.GetStoreAssociationSetEnd(1);

            var associationEndMember1 = GenerateAssociationEndMember(
                mappingContext,
                associationSetEndDetails1.AssociationSetEnd.CorrespondingAssociationEndMember,
                uniqueEndMemberNames,
                associationSetEndDetails1.Multiplicity,
                associationSetEndDetails1.DeleteBehavior);
            var conceptualEntitySet1 = mappingContext[associationSetEndDetails1.AssociationSetEnd.EntitySet];

            globallyUniqueTypeNames.UnregisterIdentifier(mappingContext[collapsibleItem.EntitySet.ElementType].Name);
            uniqueEntityContainerNames.UnregisterIdentifier(mappingContext[collapsibleItem.EntitySet].Name);

            var associationTypeName = CreateModelName(collapsibleItem.EntitySet.Name, globallyUniqueTypeNames);
            var associationSetName = CreateModelName(collapsibleItem.EntitySet.Name, uniqueEntityContainerNames);

            var conceptualAssociationType = AssociationType.Create(
                associationTypeName,
                _namespaceName,
                false,
                DataSpace.CSpace,
                associationEndMember0,
                associationEndMember1,
                null, // Don't need a referential constraint.
                null);

            CreateModelNavigationProperties(conceptualAssociationType);

            var conceptualAssociationSet = AssociationSet.Create(
                associationSetName,
                conceptualAssociationType,
                conceptualEntitySet0,
                conceptualEntitySet1,
                null);

            Debug.Assert(conceptualAssociationSet.AssociationSetEnds.Count == 2);
            var conceptualSetEnd0 = conceptualAssociationSet.AssociationSetEnds[0];
            var conceptualSetEnd1 = conceptualAssociationSet.AssociationSetEnds[1];

            mappingContext.AddMapping(associationSetEndDetails0.AssociationSetEnd, conceptualSetEnd0);
            mappingContext.AddMapping(associationSetEndDetails1.AssociationSetEnd, conceptualSetEnd1);
            mappingContext.AddMapping(collapsibleItem, conceptualAssociationSet);
            mappingContext.RemoveMapping(collapsibleItem.EntitySet);
        }
        // internal for testing
        internal ComplexType CreateComplexTypeFromRowType(SimpleMappingContext mappingContext, RowType rowType, string typeName)
        {
            Debug.Assert(mappingContext != null, "mappingContext != null");
            Debug.Assert(!string.IsNullOrEmpty(typeName), "typeName cannot be null or empty string.");
            Debug.Assert(rowType != null, "rowType != null");

            var uniquePropertyNameService = new UniqueIdentifierService();
            uniquePropertyNameService.AdjustIdentifier(typeName);

            return
                ComplexType.Create(
                    typeName,
                    _namespaceName,
                    DataSpace.CSpace,
                    rowType.Properties.Select(p => GenerateScalarProperty(mappingContext, p, uniquePropertyNameService)),
                    null);
        }
示例#19
0
        private void GenerateAssociationSet(
            SimpleMappingContext mappingContext,
            CollapsibleEntityAssociationSets collapsibleItem,
            UniqueIdentifierService uniqueEntityContainerNames,
            UniqueIdentifierService globallyUniqueTypeNames)
        {
            var uniqueEndMemberNames = new UniqueIdentifierService(StringComparer.OrdinalIgnoreCase);

            var associationSetEndDetails0 = collapsibleItem.GetStoreAssociationSetEnd(0);

            var associationEndMember0 = GenerateAssociationEndMember(
                mappingContext,
                associationSetEndDetails0.AssociationSetEnd.CorrespondingAssociationEndMember,
                uniqueEndMemberNames,
                associationSetEndDetails0.Multiplicity,
                associationSetEndDetails0.DeleteBehavior);
            var conceptualEntitySet0 = mappingContext[associationSetEndDetails0.AssociationSetEnd.EntitySet];

            var associationSetEndDetails1 =
                collapsibleItem.GetStoreAssociationSetEnd(1);

            var associationEndMember1 = GenerateAssociationEndMember(
                mappingContext,
                associationSetEndDetails1.AssociationSetEnd.CorrespondingAssociationEndMember,
                uniqueEndMemberNames,
                associationSetEndDetails1.Multiplicity,
                associationSetEndDetails1.DeleteBehavior);
            var conceptualEntitySet1 = mappingContext[associationSetEndDetails1.AssociationSetEnd.EntitySet];

            globallyUniqueTypeNames.UnregisterIdentifier(mappingContext[collapsibleItem.EntitySet.ElementType].Name);
            uniqueEntityContainerNames.UnregisterIdentifier(mappingContext[collapsibleItem.EntitySet].Name);

            var associationTypeName = CreateModelName(collapsibleItem.EntitySet.Name, globallyUniqueTypeNames);
            var associationSetName  = CreateModelName(collapsibleItem.EntitySet.Name, uniqueEntityContainerNames);

            var conceptualAssociationType = AssociationType.Create(
                associationTypeName,
                _namespaceName,
                false,
                DataSpace.CSpace,
                associationEndMember0,
                associationEndMember1,
                null, // Don't need a referential constraint.
                null);

            CreateModelNavigationProperties(conceptualAssociationType);

            var conceptualAssociationSet = AssociationSet.Create(
                associationSetName,
                conceptualAssociationType,
                conceptualEntitySet0,
                conceptualEntitySet1,
                null);

            Debug.Assert(conceptualAssociationSet.AssociationSetEnds.Count == 2);
            var conceptualSetEnd0 = conceptualAssociationSet.AssociationSetEnds[0];
            var conceptualSetEnd1 = conceptualAssociationSet.AssociationSetEnds[1];

            mappingContext.AddMapping(associationSetEndDetails0.AssociationSetEnd, conceptualSetEnd0);
            mappingContext.AddMapping(associationSetEndDetails1.AssociationSetEnd, conceptualSetEnd1);
            mappingContext.AddMapping(collapsibleItem, conceptualAssociationSet);
            mappingContext.RemoveMapping(collapsibleItem.EntitySet);
        }
        // internal for testing
        internal static FunctionParameter[] CreateFunctionImportParameters(SimpleMappingContext mappingContext, EdmFunction storeFunction)
        {
            Debug.Assert(mappingContext != null, "mappingContext != null");
            Debug.Assert(storeFunction != null, "storeFunctionParameters != null");

            var functionImportParameters = new FunctionParameter[storeFunction.Parameters.Count];

            var uniqueParameterNames = new UniqueIdentifierService();

            for (var idx = 0; idx < storeFunction.Parameters.Count; idx++)
            {
                Debug.Assert(storeFunction.Parameters[idx].Mode == ParameterMode.In, "Only In parameters are supported.");

                var parameterName = CreateModelName(storeFunction.Parameters[idx].Name, uniqueParameterNames);

                if (parameterName != storeFunction.Parameters[idx].Name)
                {
                    mappingContext.Errors.Add(
                        new EdmSchemaError(
                            string.Format(
                                CultureInfo.InvariantCulture,
                                Resources_VersioningFacade.UnableToGenerateFunctionImportParameterName,
                                storeFunction.Parameters[idx].Name,
                                storeFunction.Name),
                            (int)ModelBuilderErrorCode.UnableToGenerateFunctionImportParameterName,
                            EdmSchemaErrorSeverity.Warning));
                    return null;
                }

                functionImportParameters[idx] =
                    FunctionParameter.Create(
                        parameterName,
                        storeFunction.Parameters[idx].TypeUsage.ModelTypeUsage.EdmType,
                        storeFunction.Parameters[idx].Mode);
            }

            return functionImportParameters;
        }
        // internal for testing
        internal EdmFunction GenerateFunction(
            SimpleMappingContext mappingContext,
            EdmFunction storeFunction,
            UniqueIdentifierService uniqueEntityContainerNames,
            UniqueIdentifierService globallyUniqueTypeNames)
        {
            Debug.Assert(mappingContext != null, "mappingContext != null");
            Debug.Assert(storeFunction != null, "storeFunction != null");
            Debug.Assert(uniqueEntityContainerNames != null, "uniqueEntityContainerNames != null");
            Debug.Assert(globallyUniqueTypeNames != null, "globallyUniqueTypeNames != null");

            var tvfReturnType = GetStoreTvfReturnType(mappingContext, storeFunction);
            if (tvfReturnType == null)
            {
                return null;
            }

            var parameters = CreateFunctionImportParameters(mappingContext, storeFunction);
            if (parameters == null)
            {
                return null;
            }

            var functionImportName = CreateModelName(storeFunction.Name, uniqueEntityContainerNames);
            var returnTypeName = CreateModelName(functionImportName + "_Result", globallyUniqueTypeNames);
            var returnParameter =
                FunctionParameter.Create(
                    "ReturnType",
                    CreateComplexTypeFromRowType(mappingContext, tvfReturnType, returnTypeName).GetCollectionType(),
                    ParameterMode.ReturnValue);

            return
                EdmFunction.Create(
                    functionImportName,
                    _namespaceName,
                    DataSpace.CSpace,
                    new EdmFunctionPayload
                        {
                            Parameters = parameters,
                            ReturnParameters = new[] { returnParameter },
                            IsComposable = true,
                            IsFunctionImport = true
                        },
                    null);
        }
        // internal for testing
        internal IEnumerable<EdmFunction> GenerateFunctions(
            SimpleMappingContext mappingContext,
            EdmModel storeModel,
            UniqueIdentifierService uniqueEntityContainerNames,
            UniqueIdentifierService globallyUniqueTypeNames)
        {
            Debug.Assert(mappingContext != null, "mappingContext != null");
            Debug.Assert(storeModel != null, "storeModel != null");
            Debug.Assert(uniqueEntityContainerNames != null, "uniqueEntityContainerNames != null");
            Debug.Assert(globallyUniqueTypeNames != null, "globallyUniqueTypeNames != null");

            // TODO: Note we import only TVFs here and other store functions are 
            // imported elsewhere - ideally we import all functions in one place
            // http://entityframework.codeplex.com/workitem/925
            if (EntityFrameworkVersion.DoubleToVersion(storeModel.SchemaVersion) < EntityFrameworkVersion.Version3)
            {
                yield break;
            }

            foreach (var storeFunction in storeModel.Functions)
            {
                if (storeFunction.IsComposableAttribute
                    && !storeFunction.AggregateAttribute
                    &&
                    storeFunction.Parameters.All(p => p.Mode == ParameterMode.In))
                {
                    var functionImport = GenerateFunction(
                        mappingContext,
                        storeFunction,
                        uniqueEntityContainerNames,
                        globallyUniqueTypeNames);

                    if (functionImport != null)
                    {
                        mappingContext.AddMapping(storeFunction, functionImport);

                        yield return functionImport;
                    }
                }
            }
        }
 private static void LoadNameLookupWithUsedMemberNames(EntityType entityType, UniqueIdentifierService uniqueMemberNames)
 {
     // A property should not have the same name as its entity
     uniqueMemberNames.RegisterUsedIdentifier(entityType.Name);
     foreach (var member in entityType.Members)
     {
         uniqueMemberNames.RegisterUsedIdentifier(member.Name);
     }
 }
        private void CreateModelNavigationProperty(AssociationEndMember from, AssociationEndMember to)
        {
            var entityType = (EntityType)((RefType)from.TypeUsage.EdmType).ElementType;
            var uniqueMemberNames = new UniqueIdentifierService(StringComparer.OrdinalIgnoreCase);

            LoadNameLookupWithUsedMemberNames(entityType, uniqueMemberNames);

            var name = CreateModelName(GetNavigationPropertyName(_pluralizationService, to, to.Name), uniqueMemberNames);
            var navigationProperty = NavigationProperty.Create(
                name,
                to.TypeUsage,
                (AssociationType)to.DeclaringType,
                from,
                to,
                null);

            entityType.AddNavigationProperty(navigationProperty);
        }
        // internal for testing
        internal IEnumerable<FunctionParameter> CreateFunctionParameters(
            IList<FunctionDetailsRowView> functionDetailsRows, IList<EdmSchemaError> errors)
        {
            Debug.Assert(functionDetailsRows != null, "functionDetailsRows != null");
            Debug.Assert(errors != null, "errors != null");

            var uniqueIdentifierService = new UniqueIdentifierService();
            var parameterIdx = 0;

            return
                functionDetailsRows
                    .Select(
                        functionDetailsRow =>
                        CreateFunctionParameter(functionDetailsRow, uniqueIdentifierService, parameterIdx++, errors))
                    .Where(p => p != null);
        }
        private static AssociationEndMember GenerateAssociationEndMember(
            SimpleMappingContext mappingContext,
            AssociationEndMember storeEndMember,
            UniqueIdentifierService uniqueEndMemberNames,
            KeyValuePair<string, RelationshipMultiplicity> multiplicityOverride)
        {
            var multiplicity = (multiplicityOverride.Key != null && multiplicityOverride.Key == storeEndMember.Name)
                                   ? multiplicityOverride.Value
                                   : storeEndMember.RelationshipMultiplicity;

            return GenerateAssociationEndMember(
                mappingContext,
                storeEndMember,
                uniqueEndMemberNames,
                multiplicity,
                storeEndMember.DeleteBehavior);
        }
        internal AssociationSet TryCreateAssociationSet(
            List<RelationshipDetailsRow> relationshipDetailsRows,
            EntityRegister entityRegister,
            List<AssociationType> associationTypes)
        {
            Debug.Assert(relationshipDetailsRows.Count > 0, "relationshipDetailsRows.Count > 0");

            var firstRow = relationshipDetailsRows.First();
            var errors = new List<EdmSchemaError>();

            AssociationType associationType;
            var isValidAssociationType = false;
            var typeName = _usedTypeNames.AdjustIdentifier(firstRow.RelationshipName);
            AssociationEndMember pkEnd = null;
            AssociationEndMember fkEnd = null;
            ReferentialConstraint constraint = null;

            var pkEntityType = TryGetEndEntity(entityRegister, firstRow.GetMostQualifiedPrimaryKey(), errors);
            var fkEntityType = TryGetEndEntity(entityRegister, firstRow.GetMostQualifiedForeignKey(), errors);

            if (ValidateEndEntities(relationshipDetailsRows, pkEntityType, fkEntityType, errors))
            {
                var someFKColumnsAreNullable =
                    _targetEntityFrameworkVersion == EntityFrameworkVersion.Version1
                        ? AreAllFKColumnsNullable(relationshipDetailsRows, fkEntityType)
                        : AreAnyFKColumnsNullable(relationshipDetailsRows, fkEntityType);

                var usedEndNames = new UniqueIdentifierService(StringComparer.OrdinalIgnoreCase);

                pkEnd = AssociationEndMember.Create(
                    usedEndNames.AdjustIdentifier(pkEntityType.Name),
                    pkEntityType.GetReferenceType(),
                    someFKColumnsAreNullable
                        ? RelationshipMultiplicity.ZeroOrOne
                        : RelationshipMultiplicity.One,
                    firstRow.RelationshipIsCascadeDelete
                        ? OperationAction.Cascade
                        : OperationAction.None,
                    null);

                fkEnd = AssociationEndMember.Create(
                    usedEndNames.AdjustIdentifier(fkEntityType.Name),
                    fkEntityType.GetReferenceType(),
                    !someFKColumnsAreNullable && AreRelationshipColumnsTheFullKey(relationshipDetailsRows, fkEntityType, r => r.FKColumn)
                        ? RelationshipMultiplicity.ZeroOrOne
                        : RelationshipMultiplicity.Many,
                    OperationAction.None,
                    null);

                constraint = TryCreateReferentialConstraint(relationshipDetailsRows, pkEnd, fkEnd, errors);
                if (constraint != null
                    && ValidateReferentialConstraint(constraint, _generateForeignKeyProperties, typeName, associationTypes, errors))
                {
                    isValidAssociationType = true;
                }
            }

            associationType = AssociationType.Create(
                typeName,
                _namespaceName,
                false,
                DataSpace.SSpace,
                pkEnd,
                fkEnd,
                constraint,
                CreateMetadataProperties(!isValidAssociationType, errors));

            associationTypes.Add(associationType);

            return isValidAssociationType
                       ? CreateAssociationSet(associationType, entityRegister)
                       : null;
        }
        private static string CreateModelName(string storeName, UniqueIdentifierService uniqueNameService)
        {
            Debug.Assert(!string.IsNullOrEmpty(storeName), "storeName cannot be null or empty string");
            Debug.Assert(uniqueNameService != null, "uniqueNameService != null");

            return uniqueNameService.AdjustIdentifier(CreateModelName(storeName));
        }
        // internal for testing
        internal FunctionParameter CreateFunctionParameter(
            FunctionDetailsRowView functionDetailsRow, UniqueIdentifierService uniqueIdentifierService, int parameterIndex,
            IList<EdmSchemaError> errors)
        {
            Debug.Assert(functionDetailsRow != null, "functionDetailsRow != null");
            Debug.Assert(uniqueIdentifierService != null, "uniqueIdentifierService != null");
            Debug.Assert(errors != null, "errors != null");

            var parameterType = GetFunctionParameterType(functionDetailsRow, parameterIndex, errors);
            if (parameterType == null)
            {
                return null;
            }

            ParameterMode parameterMode;
            if (!functionDetailsRow.TryGetParameterMode(out parameterMode))
            {
                errors.Add(
                    new EdmSchemaError(
                        string.Format(
                            CultureInfo.InvariantCulture,
                            Resources_VersioningFacade.ParameterDirectionNotValid,
                            functionDetailsRow.ProcedureName,
                            functionDetailsRow.ParameterName,
                            functionDetailsRow.ProcParameterMode),
                        (int)ModelBuilderErrorCode.ParameterDirectionNotValid,
                        EdmSchemaErrorSeverity.Warning));
                return null;
            }

            var parameterName =
                uniqueIdentifierService.AdjustIdentifier(
                    ModelGeneratorUtils.CreateValidEcmaName(functionDetailsRow.ParameterName, 'p'));

            return FunctionParameter.Create(parameterName, parameterType, parameterMode);
        }
        // internal for testing
        internal static EdmProperty GenerateScalarProperty(
            SimpleMappingContext mappingContext, EdmProperty storeProperty, UniqueIdentifierService uniquePropertyNameService)
        {
            Debug.Assert(storeProperty != null, "storeProperty != null");
            Debug.Assert(uniquePropertyNameService != null, "uniquePropertyNameService != null");

            var conceptualPropertyName = CreateModelName(storeProperty.Name, uniquePropertyNameService);

            var conceptualProperty =
                EdmProperty.Create(conceptualPropertyName, storeProperty.TypeUsage.ModelTypeUsage);

            if (storeProperty.StoreGeneratedPattern != StoreGeneratedPattern.None)
            {
                conceptualProperty.SetMetadataProperties(
                    new List<MetadataProperty>
                        {
                            CreateAnnotationMetadataProperty(
                                "StoreGeneratedPattern",
                                Enum.GetName(
                                    typeof(StoreGeneratedPattern),
                                    storeProperty.StoreGeneratedPattern))
                        });
            }

            mappingContext.AddMapping(storeProperty, conceptualProperty);

            return conceptualProperty;
        }
        private void GenerateAssociationSet(
            SimpleMappingContext mappingContext,
            AssociationSet storeAssociationSet,
            UniqueIdentifierService uniqueEntityContainerNames,
            UniqueIdentifierService globallyUniqueTypeNames)
        {
            // We will get a value when the same association type is used for multiple association sets.
            AssociationType conceptualAssociationType;
            if (!mappingContext.TryGetValue(storeAssociationSet.ElementType, out conceptualAssociationType))
            {
                conceptualAssociationType = GenerateAssociationType(
                    mappingContext,
                    storeAssociationSet.ElementType,
                    globallyUniqueTypeNames);
            }

            Debug.Assert(storeAssociationSet.AssociationSetEnds.Count == 2);
            var storeSetEnd0 = storeAssociationSet.AssociationSetEnds[0];
            var storeSetEnd1 = storeAssociationSet.AssociationSetEnds[1];

            EntitySet conceptualEntitySet0, conceptualEntitySet1;
            mappingContext.TryGetValue(storeSetEnd0.EntitySet, out conceptualEntitySet0);
            mappingContext.TryGetValue(storeSetEnd1.EntitySet, out conceptualEntitySet1);

            var conceptualAssociationSet = AssociationSet.Create(
                CreateModelName(storeAssociationSet.Name, uniqueEntityContainerNames),
                conceptualAssociationType,
                conceptualEntitySet0,
                conceptualEntitySet1,
                null);

            Debug.Assert(conceptualAssociationSet.AssociationSetEnds.Count == 2);
            var conceptualSetEnd0 = conceptualAssociationSet.AssociationSetEnds[0];
            var conceptualSetEnd1 = conceptualAssociationSet.AssociationSetEnds[1];

            mappingContext.AddMapping(storeAssociationSet, conceptualAssociationSet);
            mappingContext.AddMapping(storeSetEnd0, conceptualSetEnd0);
            mappingContext.AddMapping(storeSetEnd1, conceptualSetEnd1);
        }
            public void CreateFunctionParameter_applies_ECMA_name_conversion_and_uniquifies_parameter_name()
            {
                var errors = new List<EdmSchemaError>();
                var uniquifiedIdentifierService = new UniqueIdentifierService();
                uniquifiedIdentifierService.AdjustIdentifier("p_r_m");

                var parameter = CreateStoreModelBuilder()
                    .CreateFunctionParameter(
                        CreateFunctionDetailsRow(
                            functionName: "function", paramName: "p@r@m", paramTypeName: "smallint", parameterDirection: "INOUT"),
                        uniquifiedIdentifierService,
                        1, errors);

                Assert.NotNull(parameter);
                Assert.Empty(errors);
                Assert.Equal("p_r_m1", parameter.Name);
                Assert.Equal("smallint", parameter.TypeUsage.EdmType.Name);
                Assert.Equal(ParameterMode.InOut, parameter.Mode);
            }
        // internal for testing
        internal EntityType GenerateEntityType(
            SimpleMappingContext mappingContext, EntityType storeEntityType, UniqueIdentifierService globallyUniqueTypeNames)
        {
            Debug.Assert(mappingContext != null, "mappingContext != null");
            Debug.Assert(storeEntityType != null, "storeEntityType != null");
            Debug.Assert(globallyUniqueTypeNames != null, "globallyUniqueTypeNames != null");

            var conceptualEntityTypeName = CreateModelName(
                (_pluralizationService != null) ? _pluralizationService.Singularize(storeEntityType.Name) : storeEntityType.Name,
                globallyUniqueTypeNames);

            var uniquePropertyNameService = new UniqueIdentifierService();
            uniquePropertyNameService.AdjustIdentifier(conceptualEntityTypeName);

            var edmMembers = new List<EdmMember>();
            var keyMemberNames = new List<string>();

            foreach (var storeProperty in storeEntityType.Properties)
            {
                // cannot skip this even if the store property is foreign key and generating foreign keys is disabled 
                // since it creates property mappings the will be used when mapping association types.
                var conceptualProperty = GenerateScalarProperty(mappingContext, storeProperty, uniquePropertyNameService);

                if (_generateForeignKeyProperties
                    || !mappingContext.StoreForeignKeyProperties.Contains(storeProperty)
                    || storeEntityType.KeyMembers.Contains(storeProperty))
                {
                    edmMembers.Add(conceptualProperty);
                    if (storeEntityType.KeyMembers.Contains(storeProperty))
                    {
                        keyMemberNames.Add(conceptualProperty.Name);
                    }
                }
            }

            var conceptualEntity = EntityType.Create(
                conceptualEntityTypeName, _namespaceName, DataSpace.CSpace, keyMemberNames, edmMembers, null);

            mappingContext.AddMapping(storeEntityType, conceptualEntity);

            return conceptualEntity;
        }
        private AssociationType GenerateAssociationType(
            SimpleMappingContext mappingContext,
            AssociationType storeAssociationType,
            UniqueIdentifierService globallyUniqueTypeNames)
        {
            Debug.Assert(storeAssociationType.RelationshipEndMembers.Count == 2);

            var storeEndMember0 = (AssociationEndMember)storeAssociationType.RelationshipEndMembers[0];
            var storeEndMember1 = (AssociationEndMember)storeAssociationType.RelationshipEndMembers[1];

            var storeSchemaVersion = EntityFrameworkVersion.DoubleToVersion(mappingContext.StoreModel.SchemaVersion);
            var isFkAssociation = storeSchemaVersion > EntityFrameworkVersion.Version1
                                  && (_generateForeignKeyProperties || RequiresReferentialConstraint(storeAssociationType));

            var uniqueEndMemberNames = new UniqueIdentifierService(StringComparer.OrdinalIgnoreCase);
            var multiplicityOverride = GetMultiplicityOverride(storeAssociationType);

            var conceptualEndMember0 = GenerateAssociationEndMember(
                mappingContext,
                storeEndMember0,
                uniqueEndMemberNames,
                multiplicityOverride);

            var conceptualEndMember1 = GenerateAssociationEndMember(
                mappingContext,
                storeEndMember1,
                uniqueEndMemberNames,
                multiplicityOverride);

            var conceptualAssociationType = AssociationType.Create(
                CreateModelName(storeAssociationType.Name, globallyUniqueTypeNames),
                _namespaceName,
                isFkAssociation,
                DataSpace.CSpace,
                conceptualEndMember0,
                conceptualEndMember1,
                CreateReferentialConstraint(mappingContext, storeAssociationType),
                null);

            CreateModelNavigationProperties(conceptualAssociationType);

            mappingContext.AddMapping(storeAssociationType, conceptualAssociationType);

            return conceptualAssociationType;
        }