public void FindFunctions_creates_function_descriptors_for_functions_returning_complex_types_non_composable() { var model = CreateModel(); model.ConceptualModel.AddItem(CreateComplexType()); var mockType = new Mock <Type>(); mockType .Setup(t => t.GetMethods(It.IsAny <BindingFlags>())) .Returns(typeof(Fake) .GetMethods() .Where(m => m.Name == "StoredProcToComplexTypes") .ToArray()); var functionDescriptor = new FunctionDiscovery(model, mockType.Object) .FindFunctions().SingleOrDefault(); Assert.NotNull(functionDescriptor); Assert.Equal("StoredProcToComplexTypes", functionDescriptor.Name); Assert.Equal(0, functionDescriptor.Parameters.Count()); Assert.Equal("Model.TestComplexType", functionDescriptor.ReturnTypes[0].FullName); Assert.Equal(functionDescriptor.StoreFunctionKind, StoreFunctionKind.StoredProcedure); }
public void FindFunctions_creates_function_descriptors_for_functions_taking_ObjectParameter_non_composable() { var model = CreateModel(); model.ConceptualModel.AddItem(CreateComplexType()); model.ConceptualModel.AddItem(CreateEnumType()); var mockType = new Mock <Type>(); mockType .Setup(t => t.GetMethods(It.IsAny <BindingFlags>())) .Returns(typeof(Fake) .GetMethods() .Where(m => m.Name == "StoredProcWithObjectParamater") .ToArray()); var functionDescriptor = new FunctionDiscovery(model, mockType.Object) .FindFunctions().SingleOrDefault(); Assert.NotNull(functionDescriptor); Assert.Equal("StoredProcWithObjectParamater", functionDescriptor.Name); var param = functionDescriptor.Parameters.SingleOrDefault(); Assert.NotNull(param); Assert.Equal("param", param.Name); Assert.Equal("Model.TestEnumType", param.EdmType.FullName); Assert.True(param.IsOutParam); }
public void FindFunctions_creates_function_descriptors_taking_and_returning_nullable_enums() { var model = CreateModel(); model.ConceptualModel.AddItem(CreateEnumType()); var mockType = new Mock <Type>(); mockType .Setup(t => t.GetMethods(It.IsAny <BindingFlags>())) .Returns(typeof(Fake) .GetMethods() .Where(m => m.Name == "EnumFunctionImportWithNullableEnums") .ToArray()); var functionDescriptor = new FunctionDiscovery(model, mockType.Object) .FindFunctions().SingleOrDefault(); Assert.NotNull(functionDescriptor); Assert.Equal("EnumFunctionImportWithNullableEnums", functionDescriptor.Name); Assert.Equal(1, functionDescriptor.Parameters.Count()); Assert.Equal("Model.TestEnumType", functionDescriptor.ReturnTypes[0].FullName); Assert.Equal(functionDescriptor.StoreFunctionKind, StoreFunctionKind.TableValuedFunction); }
public void FindFunctions_ignores_empty_ResultTypes_for_non_composable() { var mockType = new Mock<Type>(); mockType .Setup(t => t.GetMethods(It.IsAny<BindingFlags>())) .Returns(new[] {typeof (Fake).GetMethod("EmptyResultType")}); var returnType = new FunctionDiscovery(CreateModel(), mockType.Object) .FindFunctions() .ToArray()[0].ReturnTypes[0]; Assert.Contains("Edm.Int32", returnType.FullName); }
public void FindFunctions_creates_function_descriptors_with_custom_names() { var mockType = new Mock<Type>(); mockType .Setup(t => t.GetMethods(It.IsAny<BindingFlags>())) .Returns(typeof (Fake) .GetMethods() .Where(m => m.Name == "FuncWithDifferentNames") .ToArray()); var functionDescriptor = new FunctionDiscovery(CreateModel(), mockType.Object) .FindFunctions().Single(); Assert.NotNull(functionDescriptor); Assert.Equal("storeFuncName", functionDescriptor.Name); }
public void FindFunctions_creates_function_descriptors_for_built_in_function() { var mockType = new Mock<Type>(); mockType .Setup(t => t.GetMethods(It.IsAny<BindingFlags>())) .Returns(new[] { typeof(Fake).GetMethod("BuiltInFunction") }); var functionDescriptor = new FunctionDiscovery(CreateModel(), mockType.Object) .FindFunctions().SingleOrDefault(); Assert.NotNull(functionDescriptor); Assert.Single(functionDescriptor.Parameters); Assert.Equal("param", functionDescriptor.Parameters.First().Name); Assert.Equal("Edm.String", functionDescriptor.Parameters.First().EdmType.FullName); Assert.Equal("Edm.Int32", functionDescriptor.ReturnTypes[0].FullName); Assert.True(functionDescriptor.IsBuiltIn); }
public void FindFunctions_creates_function_descriptors_for_primitive_udfs() { var mockType = new Mock<Type>(); mockType .Setup(t => t.GetMethods(It.IsAny<BindingFlags>())) .Returns(new[] { typeof(Fake).GetMethod("ScalarUdfPrimitiveType") }); var functionDescriptor = new FunctionDiscovery(CreateModel(), mockType.Object) .FindFunctions().SingleOrDefault(); Assert.NotNull(functionDescriptor); Assert.Single(functionDescriptor.Parameters); Assert.Equal("param", functionDescriptor.Parameters.First().Name); Assert.Equal("Edm.String", functionDescriptor.Parameters.First().EdmType.FullName); Assert.Equal("Edm.Int32", functionDescriptor.ReturnTypes[0].FullName); Assert.Equal(StoreFunctionKind.ScalarUserDefinedFunction, functionDescriptor.StoreFunctionKind); }
public void FindFunctions_creates_function_private() { var mockType = new Mock<Type>(); mockType .Setup(t => t.GetMethods(It.IsAny<BindingFlags>())) .Returns(typeof(Fake) .GetMethods(BindingFlags.Instance | BindingFlags.NonPublic) .Where(m => m.Name == "PrivateFunction") .ToArray()); var functionDescriptor = new FunctionDiscovery(CreateModel(), mockType.Object) .FindFunctions().Single(); Assert.NotNull(functionDescriptor); Assert.Equal("PrivateFunction", functionDescriptor.Name); Assert.Single(functionDescriptor.Parameters); Assert.Equal("Edm.Int32", functionDescriptor.ReturnTypes[0].FullName); Assert.Equal(StoreFunctionKind.TableValuedFunction, functionDescriptor.StoreFunctionKind); }
public void FindFunctions_creates_function_descriptors_returning_primitive_types() { var mockType = new Mock<Type>(); mockType .Setup(t => t.GetMethods(It.IsAny<BindingFlags>())) .Returns(typeof (Fake) .GetMethods() .Where(m => m.Name == "PrimitiveFunctionImportComposable" || m.Name == "NotAFunctionImport") .ToArray()); var functionDescriptor = new FunctionDiscovery(CreateModel(), mockType.Object) .FindFunctions().Single(); Assert.NotNull(functionDescriptor); Assert.Equal("PrimitiveFunctionImportComposable", functionDescriptor.Name); Assert.Equal(2, functionDescriptor.Parameters.Count()); Assert.Equal("Edm.Int32", functionDescriptor.ReturnTypes[0].FullName); Assert.Equal(StoreFunctionKind.TableValuedFunction, functionDescriptor.StoreFunctionKind); }
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? }
public void FindFunctions_creates_function_descriptors_for_extension_methods() { var mockType = new Mock<Type>(); mockType .Setup(t => t.GetMethods(It.IsAny<BindingFlags>())) .Returns(new[] {typeof (StaticFake).GetMethod("ExtensionMethod")}); mockType .Protected() .Setup<TypeAttributes>("GetAttributeFlagsImpl") .Returns(TypeAttributes.Abstract | TypeAttributes.Sealed); var functionDescriptor = new FunctionDiscovery(CreateModel(), mockType.Object) .FindFunctions().SingleOrDefault(); Assert.NotNull(functionDescriptor); Assert.Equal("ExtensionMethod", functionDescriptor.Name); Assert.Single(functionDescriptor.Parameters); Assert.Equal("param", functionDescriptor.Parameters.First().Name); Assert.Equal("Edm.String", functionDescriptor.Parameters.First().EdmType.FullName); Assert.Equal("Edm.Int32", functionDescriptor.ReturnTypes[0].FullName); Assert.Equal(StoreFunctionKind.TableValuedFunction, functionDescriptor.StoreFunctionKind); }
public void FindFunctions_creates_function_descriptors_returning_complex_types() { var model = CreateModel(); model.ConceptualModel.AddItem(CreateComplexType()); var mockType = new Mock<Type>(); mockType .Setup(t => t.GetMethods(It.IsAny<BindingFlags>())) .Returns(typeof (Fake) .GetMethods() .Where(m => m.Name == "FunctionImportReturningComplexTypesComposable") .ToArray()); var functionDescriptor = new FunctionDiscovery(model, mockType.Object) .FindFunctions().Single(); Assert.NotNull(functionDescriptor); Assert.Equal("FunctionImportReturningComplexTypesComposable", functionDescriptor.Name); Assert.Empty(functionDescriptor.Parameters); Assert.Equal("Model.TestComplexType", functionDescriptor.ReturnTypes[0].FullName); Assert.Equal(StoreFunctionKind.TableValuedFunction, functionDescriptor.StoreFunctionKind); }
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? }