private static void BuildSPRenamediagram(DbModel model, ReadOnlyCollection <PrimitiveType> storeTypes) { EdmFunctionPayload payload = new EdmFunctionPayload { Schema = "dbo", StoreFunctionName = "sp_renamediagram", IsComposable = false }; payload.Parameters = new List <FunctionParameter>(); payload.Parameters.Add(FunctionParameter.Create("diagramname", GetEdmType(model, storeTypes, PrimitiveTypeKind.String), ParameterMode.In)); payload.Parameters.Add(FunctionParameter.Create("owner_id", GetEdmType(model, storeTypes, PrimitiveTypeKind.Int32), ParameterMode.In)); payload.Parameters.Add(FunctionParameter.Create("new_diagramname", GetEdmType(model, storeTypes, PrimitiveTypeKind.String), ParameterMode.In)); EdmFunction function = EdmFunction.Create("sp_renamediagram", "CodeFirstDatabaseSchema", DataSpace.SSpace, payload, null); model.StoreModel.AddItem(function); EdmFunctionPayload payloadImport = new EdmFunctionPayload { IsFunctionImport = true, IsComposable = false }; payloadImport.Parameters = new List <FunctionParameter>(); payloadImport.Parameters.Add(FunctionParameter.Create("diagramname", PrimitiveType.GetEdmPrimitiveType(PrimitiveTypeKind.String), ParameterMode.In)); payloadImport.Parameters.Add(FunctionParameter.Create("owner_id", PrimitiveType.GetEdmPrimitiveType(PrimitiveTypeKind.Int32), ParameterMode.In)); payloadImport.Parameters.Add(FunctionParameter.Create("new_diagramname", PrimitiveType.GetEdmPrimitiveType(PrimitiveTypeKind.String), ParameterMode.In)); EdmFunction functionImport = EdmFunction.Create("sp_renamediagram", "CodeFirstNamespace", DataSpace.CSpace, payloadImport, null); model.ConceptualModel.Container.AddFunctionImport(functionImport); FunctionImportResultMapping functionImportResultMapping = null; FunctionImportMappingNonComposable functionImportMapping = CreateFunctionImportMappingNonComposable(functionImport, function, functionImportResultMapping, model.ConceptualToStoreMapping); model.ConceptualToStoreMapping.AddFunctionImportMapping(functionImportMapping); }
private void WriteFunctionImportResultMappingElement(FunctionImportResultMapping resultMapping) { this._xmlWriter.WriteStartElement("ResultMapping"); foreach (FunctionImportStructuralTypeMapping typeMapping in resultMapping.TypeMappings) { FunctionImportEntityTypeMapping entityTypeMapping = typeMapping as FunctionImportEntityTypeMapping; if (entityTypeMapping != null) { this.WriteFunctionImportEntityTypeMappingElement(entityTypeMapping); } else { this.WriteFunctionImportComplexTypeMappingElement((FunctionImportComplexTypeMapping)typeMapping); } } this._xmlWriter.WriteEndElement(); }
private void WriteFunctionImportResultMappingElement(FunctionImportResultMapping resultMapping) { DebugCheck.NotNull(resultMapping); _xmlWriter.WriteStartElement(MslConstructs.FunctionImportMappingResultMapping); foreach (var typeMapping in resultMapping.TypeMappings) { var entityTypeMapping = typeMapping as FunctionImportEntityTypeMapping; if (entityTypeMapping != null) { WriteFunctionImportEntityTypeMappingElement(entityTypeMapping); } else { WriteFunctionImportComplexTypeMappingElement((FunctionImportComplexTypeMapping)typeMapping); } } _xmlWriter.WriteEndElement(); }
private static void BuildSPUpgraddiagram(DbModel model, ReadOnlyCollection <PrimitiveType> storeTypes) { EdmFunctionPayload payload = new EdmFunctionPayload { Schema = "dbo", StoreFunctionName = "sp_upgraddiagrams", IsComposable = false }; EdmFunction function = EdmFunction.Create("sp_upgraddiagrams", "CodeFirstDatabaseSchema", DataSpace.SSpace, payload, null); model.StoreModel.AddItem(function); EdmFunctionPayload payloadImport = new EdmFunctionPayload { IsFunctionImport = true, IsComposable = false }; EdmFunction functionImport = EdmFunction.Create("sp_upgraddiagrams", "CodeFirstNamespace", DataSpace.CSpace, payloadImport, null); model.ConceptualModel.Container.AddFunctionImport(functionImport); FunctionImportResultMapping functionImportResultMapping = null; FunctionImportMappingNonComposable functionImportMapping = CreateFunctionImportMappingNonComposable(functionImport, function, functionImportResultMapping, model.ConceptualToStoreMapping); model.ConceptualToStoreMapping.AddFunctionImportMapping(functionImportMapping); }
void IStoreModelConvention <EntityContainer> .Apply(EntityContainer container, DbModel model) { foreach (MethodInfo mi in _containerType.GetMethods().Where(mi => mi.IsDefined(typeof(DbFunctionAttribute)))) { FunctionDescriptor descriptor = BuildFunctionDescriptor(mi); EdmFunction storeFunction = CreateStoreFunction(model, descriptor); model.StoreModel.AddItem(storeFunction); if (descriptor.IsTableValued) { EdmFunction functionImport = CreateFunctionImport(model, descriptor); model.ConceptualModel.Container.AddFunctionImport(functionImport); if (functionImport.IsComposableAttribute) { FunctionImportResultMapping resultMapping = new FunctionImportResultMapping(); if (functionImport.ReturnParameter.TypeUsage.EdmType.BuiltInTypeKind == BuiltInTypeKind.CollectionType) { EdmType itemType = ((CollectionType)functionImport.ReturnParameter.TypeUsage.EdmType).TypeUsage.EdmType; RowType rowType = (RowType)((CollectionType)storeFunction.ReturnParameter.TypeUsage.EdmType).TypeUsage.EdmType; if (itemType.BuiltInTypeKind == BuiltInTypeKind.ComplexType) { ComplexType complexType = (ComplexType)itemType; resultMapping.AddTypeMapping(new FunctionImportComplexTypeMapping(complexType, new Collection <FunctionImportReturnTypePropertyMapping>( complexType.Properties.Select(p => { var columnAttr = ((IEnumerable)p.MetadataProperties["ClrAttributes"].Value).OfType <ColumnAttribute>().SingleOrDefault(); return(new FunctionImportReturnTypeScalarPropertyMapping(p.Name, columnAttr != null && !string.IsNullOrEmpty(columnAttr.Name) ? columnAttr.Name : p.Name)); }).ToArray()))); } } model.ConceptualToStoreMapping.AddFunctionImportMapping((FunctionImportMapping) new FunctionImportMappingComposable(functionImport, storeFunction, resultMapping, model.ConceptualToStoreMapping)); } else { model.ConceptualToStoreMapping.AddFunctionImportMapping((FunctionImportMapping) new FunctionImportMappingNonComposable(functionImport, storeFunction, new FunctionImportResultMapping[0], model.ConceptualToStoreMapping)); } } } }
public void WriteFunctionImportMappingElement_writes_result_mapping_for_non_composable_functions_mapped_explicitly_to_EntityType() { var typeUsage = TypeUsage.CreateDefaultTypeUsage(PrimitiveType.GetEdmPrimitiveType(PrimitiveTypeKind.Int32)); var entityTypeProperty1 = new EdmProperty("ETProperty1", typeUsage); var entityTypeProperty2 = new EdmProperty("ETProperty2", typeUsage); var entityType = new EntityType("ET", "Ns", DataSpace.CSpace); entityType.AddMember(entityTypeProperty1); entityType.AddMember(entityTypeProperty2); var functionImport = new EdmFunction( "f_c", "Ns", DataSpace.CSpace, new EdmFunctionPayload { IsComposable = false, IsFunctionImport = true, ReturnParameters = new[] { new FunctionParameter( "ReturnValue", TypeUsage.CreateDefaultTypeUsage(entityType.GetCollectionType()), ParameterMode.ReturnValue) }, }); typeUsage = ProviderRegistry.Sql2008_ProviderManifest.GetStoreType(typeUsage); var rowTypeProperty1 = new EdmProperty("RTProperty1", typeUsage); var rowTypeProperty2 = new EdmProperty("RTProperty2", typeUsage); var rowType = new RowType(new[] { rowTypeProperty1, rowTypeProperty2 }); var storeFunction = new EdmFunction( "f_s", "Ns.Store", DataSpace.SSpace, new EdmFunctionPayload { IsComposable = false, ReturnParameters = new[] { new FunctionParameter( "Return", TypeUsage.CreateDefaultTypeUsage(rowType), ParameterMode.ReturnValue) }, }); var functionImportResultMapping = new FunctionImportResultMapping(); functionImportResultMapping.AddTypeMapping( new FunctionImportEntityTypeMapping( new EntityType[0], new [] { entityType }, new Collections.ObjectModel.Collection <FunctionImportReturnTypePropertyMapping>() { new FunctionImportReturnTypeScalarPropertyMapping("ETProperty1", "RTProperty1"), new FunctionImportReturnTypeScalarPropertyMapping("ETProperty2", "RTProperty2") }, new FunctionImportEntityTypeMappingCondition[] { new FunctionImportEntityTypeMappingConditionIsNull("RTProperty1", false), new FunctionImportEntityTypeMappingConditionValue("RTProperty2", 4), new FunctionImportEntityTypeMappingConditionValue("FakeCondition", true) } )); var mappingItemCollection = new StorageMappingItemCollection( new EdmItemCollection(EdmModel.CreateConceptualModel()), new StoreItemCollection( EdmModel.CreateStoreModel(ProviderRegistry.Sql2008_ProviderInfo, ProviderRegistry.Sql2008_ProviderManifest)), new string[0]); var containerMapping = new EntityContainerMapping( new EntityContainer("C", DataSpace.CSpace), new EntityContainer("S", DataSpace.SSpace), mappingItemCollection, false); var functionImportMapping = new FunctionImportMappingNonComposable( functionImport, storeFunction, new [] { functionImportResultMapping }, containerMapping); containerMapping.AddFunctionImportMapping(functionImportMapping); var fixture = new Fixture(); fixture.Writer.WriteFunctionImportMappingElement(functionImportMapping); Assert.Equal( @"<FunctionImportMapping FunctionName=""Ns.Store.f_s"" FunctionImportName=""f_c""> <ResultMapping> <EntityTypeMapping TypeName=""Ns.ET""> <ScalarProperty Name=""ETProperty1"" ColumnName=""RTProperty1"" /> <ScalarProperty Name=""ETProperty2"" ColumnName=""RTProperty2"" /> <Condition ColumnName=""RTProperty1"" IsNull=""false"" /> <Condition ColumnName=""RTProperty2"" Value=""4"" /> <Condition ColumnName=""FakeCondition"" Value=""1"" /> </EntityTypeMapping> </ResultMapping> </FunctionImportMapping>", fixture.ToString()); }
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? }