public void Crate_creates_store_function_for_complex_type_function_import()
        {
            var model = new DbModelBuilder()
                        .Build(new DbProviderInfo("System.Data.SqlClient", "2012"));

            var complexType = ComplexType.Create("CT", "ns", DataSpace.CSpace,
                                                 new[]
            {
                EdmProperty.Create("Street",
                                   TypeUsage.CreateDefaultTypeUsage(PrimitiveType.GetEdmPrimitiveType(PrimitiveTypeKind.String))),
                EdmProperty.Create("ZipCode",
                                   TypeUsage.CreateDefaultTypeUsage(PrimitiveType.GetEdmPrimitiveType(PrimitiveTypeKind.Int32))),
            },
                                                 null);

            var functionDescriptor =
                new FunctionDescriptor(
                    "f",
                    new[]
                    { new ParameterDescriptor("p1", PrimitiveType.GetEdmPrimitiveType(PrimitiveTypeKind.String), null, false) },
                    new EdmType[] { complexType },
                    "ResultCol",
                    "dbo",
                    StoreFunctionKind.StoredProcedure);

            var storeFunction = new StoreFunctionBuilder(model, "docs", "ns").Create(functionDescriptor);

            Assert.Null(storeFunction.ReturnParameter);

            Assert.Equal(1, storeFunction.Parameters.Count);
            Assert.Equal("p1", storeFunction.Parameters[0].Name);
            Assert.Equal("nvarchar(max)", storeFunction.Parameters[0].TypeName);
            Assert.Equal(ParameterMode.In, storeFunction.Parameters[0].Mode);
            Assert.False(storeFunction.IsComposableAttribute);
        }
Example #2
0
        public void Crate_creates_store_function_for_primitive_function_import()
        {
            var model = new DbModelBuilder()
                        .Build(new DbProviderInfo("System.Data.SqlClient", "2012"));

            var functionDescriptor =
                new FunctionDescriptor(
                    "f",
                    new[] {
                new ParameterDescriptor(
                    "p1", PrimitiveType.GetEdmPrimitiveType(PrimitiveTypeKind.String), null, false),
            },
                    new EdmType[] { PrimitiveType.GetEdmPrimitiveType(PrimitiveTypeKind.Int64) },
                    "ResultCol", "dbo", StoreFunctionKind.TableValuedFunction, isBuiltIn: null);

            var storeFunction = new StoreFunctionBuilder(model, "docs", "ns").Create(functionDescriptor);

            Assert.Equal(
                BuiltInTypeKind.CollectionType,
                storeFunction.ReturnParameter.TypeUsage.EdmType.BuiltInTypeKind);

            var collectionItemType =
                (RowType)((CollectionType)storeFunction.ReturnParameter.TypeUsage.EdmType).TypeUsage.EdmType;

            Assert.Equal(1, collectionItemType.Properties.Count);
            Assert.Equal("ResultCol", collectionItemType.Properties[0].Name);
            Assert.Equal("bigint", collectionItemType.Properties[0].TypeUsage.EdmType.Name);

            Assert.Equal(1, storeFunction.Parameters.Count);
            Assert.Equal("p1", storeFunction.Parameters[0].Name);
            Assert.Equal("nvarchar(max)", storeFunction.Parameters[0].TypeName);
            Assert.Equal(ParameterMode.In, storeFunction.Parameters[0].Mode);
            Assert.True(storeFunction.IsComposableAttribute);
        }
Example #3
0
        public void StoreFunctionBuilder_uses_default_namespace_if_no_entities()
        {
            var model = new DbModelBuilder()
                        .Build(new DbProviderInfo("System.Data.SqlClient", "2012"));

            var functionDescriptor =
                new FunctionDescriptor(
                    "f",
                    new[]
                    { new ParameterDescriptor("p1", PrimitiveType.GetEdmPrimitiveType(PrimitiveTypeKind.String), null, false) },
                    new EdmType[] { PrimitiveType.GetEdmPrimitiveType(PrimitiveTypeKind.Int64) },
                    "ResultCol", "dbo", StoreFunctionKind.TableValuedFunction, isBuiltIn: null);

            var storeFunction = new StoreFunctionBuilder(model, "docs").Create(functionDescriptor);

            Assert.Equal("CodeFirstDatabaseSchema", storeFunction.NamespaceName);
        }
Example #4
0
        public void Crate_creates_store_function_for_complex_type_withEnum_in_TableValuedFunction()
        {
            var model = new DbModelBuilder()
                        .Build(new DbProviderInfo("System.Data.SqlClient", "2012"));

            var enumType = EnumType.Create("TestEnum", "TestNs", PrimitiveType.GetEdmPrimitiveType(PrimitiveTypeKind.Int32), false, new EnumMember[] { EnumMember.Create("foo", 1, null) }, null);

            var complexType = ComplexType.Create("CT", "ns", DataSpace.CSpace,
                                                 new[]
            {
                EdmProperty.Create("Street",
                                   TypeUsage.CreateDefaultTypeUsage(PrimitiveType.GetEdmPrimitiveType(PrimitiveTypeKind.String))),
                EdmProperty.Create("ZipCode",
                                   TypeUsage.CreateDefaultTypeUsage(PrimitiveType.GetEdmPrimitiveType(PrimitiveTypeKind.Int32))),
                EdmProperty.Create("MyEnum", TypeUsage.CreateDefaultTypeUsage(enumType))
            },
                                                 null);

            var functionDescriptor =
                new FunctionDescriptor(
                    "f",
                    new[]
                    { new ParameterDescriptor("p1", PrimitiveType.GetEdmPrimitiveType(PrimitiveTypeKind.String), null, false) },
                    new EdmType[] { complexType },
                    "ResultCol",
                    "dbo",
                    StoreFunctionKind.TableValuedFunction,
                    isBuiltIn: null,
                    isNiladic: null);

            var storeFunction = new StoreFunctionBuilder(model, "docs", "ns").Create(functionDescriptor);

            Assert.Equal(
                BuiltInTypeKind.CollectionType,
                storeFunction.ReturnParameter.TypeUsage.EdmType.BuiltInTypeKind);

            Assert.Single(storeFunction.Parameters);
            Assert.Equal("p1", storeFunction.Parameters[0].Name);
            Assert.Equal("nvarchar(max)", storeFunction.Parameters[0].TypeName);
            Assert.Equal(ParameterMode.In, storeFunction.Parameters[0].Mode);
            Assert.True(storeFunction.IsComposableAttribute);
        }
Example #5
0
        public void Can_specify_store_type_for_parameters()
        {
            var model = new DbModelBuilder()
                        .Build(new DbProviderInfo("System.Data.SqlClient", "2012"));

            var functionDescriptor =
                new FunctionDescriptor(
                    "f",
                    new[] {
                new ParameterDescriptor(
                    "p1", PrimitiveType.GetEdmPrimitiveType(PrimitiveTypeKind.String), "xml", true),
            },
                    new EdmType[] { PrimitiveType.GetEdmPrimitiveType(PrimitiveTypeKind.Int64) },
                    "ResultCol", "dbo", StoreFunctionKind.StoredProcedure, isBuiltIn: null);

            var storeFunction = new StoreFunctionBuilder(model, "docs", "ns").Create(functionDescriptor);

            Assert.Equal(1, storeFunction.Parameters.Count);
            Assert.Equal("p1", storeFunction.Parameters[0].Name);
            Assert.Equal("xml", storeFunction.Parameters[0].TypeName);
        }
Example #6
0
        public void Crate_creates_store_function_for_enum_type_function_import()
        {
            var model = new DbModelBuilder()
                        .Build(new DbProviderInfo("System.Data.SqlClient", "2012"));

            var enumTypeCtor = typeof(EnumType).GetConstructors(BindingFlags.NonPublic | BindingFlags.Instance).Single(c => c.GetParameters().Count() == 5);
            var enumType     = (EnumType)enumTypeCtor.Invoke(BindingFlags.NonPublic | BindingFlags.Instance, null,
                                                             new object[] { "TestEnumType", "Model", PrimitiveType.GetEdmPrimitiveType(PrimitiveTypeKind.Int32), false, DataSpace.CSpace },
                                                             CultureInfo.InvariantCulture);

            var functionDescriptor =
                new FunctionDescriptor(
                    "f",
                    new[] { new ParameterDescriptor("p1", enumType, null, false) },
                    new EdmType[] { enumType },
                    "ResultCol",
                    "dbo",
                    StoreFunctionKind.TableValuedFunction,
                    isBuiltIn: null,
                    isNiladic: null);

            var storeFunction = new StoreFunctionBuilder(model, "docs", "ns").Create(functionDescriptor);

            Assert.Equal(
                BuiltInTypeKind.CollectionType,
                storeFunction.ReturnParameter.TypeUsage.EdmType.BuiltInTypeKind);

            var collectionItemType =
                (RowType)((CollectionType)storeFunction.ReturnParameter.TypeUsage.EdmType).TypeUsage.EdmType;

            Assert.Single(collectionItemType.Properties);
            Assert.Equal("ResultCol", collectionItemType.Properties[0].Name);
            Assert.Equal("int", collectionItemType.Properties[0].TypeUsage.EdmType.Name);

            Assert.Single(storeFunction.Parameters);
            Assert.Equal("p1", storeFunction.Parameters[0].Name);
            Assert.Equal("int", storeFunction.Parameters[0].TypeName);
            Assert.Equal(ParameterMode.In, storeFunction.Parameters[0].Mode);
            Assert.True(storeFunction.IsComposableAttribute);
        }
        public void Apply(EntityContainer item, DbModel model)
        {
            var functionDescriptors  = new FunctionDiscovery(model, _methodClassType).FindFunctions();
            var storeFunctionBuilder = new StoreFunctionBuilder(model, _defaultSchema);

            foreach (var functionDescriptor in functionDescriptors)
            {
                var storeFunctionDefinition = storeFunctionBuilder.Create(functionDescriptor);
                model.StoreModel.AddItem(storeFunctionDefinition);

                if (functionDescriptor.StoreFunctionKind != StoreFunctionKind.ScalarUserDefinedFunction)
                {
                    var functionImportDefinition = CreateFunctionImport(model, functionDescriptor);
                    model.ConceptualModel.Container.AddFunctionImport(functionImportDefinition);

                    if (functionImportDefinition.IsComposableAttribute)
                    {
                        model.ConceptualToStoreMapping.AddFunctionImportMapping(
                            new FunctionImportMappingComposable(
                                functionImportDefinition,
                                storeFunctionDefinition,
                                new FunctionImportResultMapping(),
                                model.ConceptualToStoreMapping));
                    }
                    else
                    {
                        model.ConceptualToStoreMapping.AddFunctionImportMapping(
                            new FunctionImportMappingNonComposable(
                                functionImportDefinition,
                                storeFunctionDefinition,
                                new FunctionImportResultMapping[0],
                                model.ConceptualToStoreMapping));
                    }
                }
            }

            // TODO: model defined functions?
        }
Example #8
0
        public void Crate_can_create_out_params()
        {
            var model = new DbModelBuilder()
                        .Build(new DbProviderInfo("System.Data.SqlClient", "2012"));

            var functionDescriptor =
                new FunctionDescriptor(
                    "f",
                    new[] {
                new ParameterDescriptor(
                    "p1", PrimitiveType.GetEdmPrimitiveType(PrimitiveTypeKind.String), null, true),
            },
                    new EdmType[] { PrimitiveType.GetEdmPrimitiveType(PrimitiveTypeKind.Int64) },
                    "ResultCol", "dbo", StoreFunctionKind.StoredProcedure, isBuiltIn: null);

            var storeFunction = new StoreFunctionBuilder(model, "docs", "ns").Create(functionDescriptor);

            Assert.Equal(1, storeFunction.Parameters.Count);
            Assert.Equal("p1", storeFunction.Parameters[0].Name);
            Assert.Equal("nvarchar(max)", storeFunction.Parameters[0].TypeName);
            Assert.Equal(ParameterMode.InOut, storeFunction.Parameters[0].Mode);
            Assert.False(storeFunction.IsComposableAttribute);
        }
Example #9
0
        public void Apply(EntityContainer item, DbModel model)
        {
            var functionDescriptors  = new FunctionDiscovery(model, _methodClassType).FindFunctions();
            var storeFunctionBuilder = new StoreFunctionBuilder(model, _defaultSchema);

            foreach (var functionDescriptor in functionDescriptors)
            {
                var storeFunctionDefinition = storeFunctionBuilder.Create(functionDescriptor);
                model.StoreModel.AddItem(storeFunctionDefinition);

                if (functionDescriptor.StoreFunctionKind != StoreFunctionKind.ScalarUserDefinedFunction)
                {
                    var functionImportDefinition = CreateFunctionImport(model, functionDescriptor);
                    model.ConceptualModel.Container.AddFunctionImport(functionImportDefinition);

                    List <FunctionImportResultMapping> resultMappings = new List <FunctionImportResultMapping>();
                    if (functionDescriptor.ReturnTypes.All(t => t is EntityType || t is ComplexType))
                    {
                        foreach (EdmType returnType in functionDescriptor.ReturnTypes)
                        {
                            FunctionImportStructuralTypeMapping typeMapping;
                            if (returnType is EntityType)
                            {
                                var entityType = (EntityType)returnType;

                                var returnTypePropertyMappings = new Collection <FunctionImportReturnTypePropertyMapping>();
                                foreach (var propertyMapping in model.GetEntityTypePropertyMappings(entityType).OfType <ScalarPropertyMapping>())
                                {
                                    returnTypePropertyMappings.Add(new FunctionImportReturnTypeScalarPropertyMapping(propertyMapping.Property.Name, propertyMapping.Column.Name));
                                }

                                typeMapping = new FunctionImportEntityTypeMapping(
                                    Enumerable.Empty <EntityType>(),
                                    new[] { entityType },
                                    returnTypePropertyMappings,
                                    Enumerable.Empty <FunctionImportEntityTypeMappingCondition>());
                            }
                            else // ComplexType
                            {
                                var complexType = (ComplexType)returnType;

                                var returnTypePropertyMappings = new Collection <FunctionImportReturnTypePropertyMapping>();
                                foreach (var property in complexType.Properties)
                                {
                                    returnTypePropertyMappings.Add(new FunctionImportReturnTypeScalarPropertyMapping(property.Name, property.Name));
                                }

                                typeMapping = new FunctionImportComplexTypeMapping(complexType, returnTypePropertyMappings);
                            }

                            FunctionImportResultMapping resultMapping = new FunctionImportResultMapping();
                            resultMappings.Add(resultMapping);
                            resultMapping.AddTypeMapping(typeMapping);
                        }
                    }

                    if (functionImportDefinition.IsComposableAttribute)
                    {
                        model.ConceptualToStoreMapping.AddFunctionImportMapping(
                            new FunctionImportMappingComposable(
                                functionImportDefinition,
                                storeFunctionDefinition,
                                resultMappings.FirstOrDefault() ?? new FunctionImportResultMapping(),
                                model.ConceptualToStoreMapping));
                    }
                    else
                    {
                        // HACK: Currently, FunctionImportMappingNonComposable ctor does not support code-first construction because
                        //       it depends on EdmItemCollection being available from StorageMappingItemCollection. Code-first does
                        //       not create a StorageMappingItemCollection and, as a result, this ctor will throw a null reference
                        //       exception if any result mappings are passed to it in code-first context. This must be resolved in
                        //       EF itself. Until then, _only composable functions can support custom named column mappings_. Once
                        //       this issue is resolved in EF then the commented code should replace the current "empty array"
                        //       resultMapping parameter to enable custom mappings for non-composable functions as well:
                        model.ConceptualToStoreMapping.AddFunctionImportMapping(
                            new FunctionImportMappingNonComposable(
                                functionImportDefinition,
                                storeFunctionDefinition,
                                // resultMappings.Any() ? resultMappings.ToArray() : new FunctionImportResultMapping[0],
                                new FunctionImportResultMapping[0],
                                model.ConceptualToStoreMapping));
                    }
                }
            }

            // TODO: model defined functions?
        }