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); }
/// <summary> /// Determines the store type for a function import. /// </summary> private TypeUsage DetermineStoreResultType(MetadataWorkspace workspace, FunctionImportMappingNonComposable mapping, int resultSetIndex, out IColumnMapGenerator columnMapGenerator) { // Determine column maps and infer result types for the mapped function. There are four varieties: // Collection(Entity) // Collection(PrimitiveType) // Collection(ComplexType) // No result type TypeUsage storeResultType; { StructuralType baseStructuralType; EdmFunction functionImport = mapping.FunctionImport; // Collection(Entity) or Collection(ComplexType) if (MetadataHelper.TryGetFunctionImportReturnType <StructuralType>(functionImport, resultSetIndex, out baseStructuralType)) { ValidateEdmResultType(baseStructuralType, functionImport); //Note: Defensive check for historic reasons, we expect functionImport.EntitySets.Count > resultSetIndex EntitySet entitySet = functionImport.EntitySets.Count > resultSetIndex ? functionImport.EntitySets[resultSetIndex] : null; columnMapGenerator = new FunctionColumnMapGenerator(mapping, resultSetIndex, entitySet, baseStructuralType); // We don't actually know the return type for the stored procedure, but we can infer // one based on the mapping (i.e.: a column for every property of the mapped types // and for all discriminator columns) storeResultType = mapping.GetExpectedTargetResultType(workspace, resultSetIndex); } // Collection(PrimitiveType) else { FunctionParameter returnParameter = MetadataHelper.GetReturnParameter(functionImport, resultSetIndex); if (returnParameter != null && returnParameter.TypeUsage != null) { // Get metadata description of the return type storeResultType = returnParameter.TypeUsage; Debug.Assert(storeResultType.EdmType.BuiltInTypeKind == BuiltInTypeKind.CollectionType, "FunctionImport currently supports only collection result type"); TypeUsage elementType = ((CollectionType)storeResultType.EdmType).TypeUsage; Debug.Assert(Helper.IsScalarType(elementType.EdmType) , "FunctionImport supports only Collection(Entity), Collection(Enum) and Collection(Primitive)"); // Build collection column map where the first column of the store result is assumed // to contain the primitive type values. ScalarColumnMap scalarColumnMap = new ScalarColumnMap(elementType, string.Empty, 0, 0); SimpleCollectionColumnMap collectionColumnMap = new SimpleCollectionColumnMap(storeResultType, string.Empty, scalarColumnMap, null, null); columnMapGenerator = new ConstantColumnMapGenerator(collectionColumnMap, 1); } // No result type else { storeResultType = null; columnMapGenerator = new ConstantColumnMapGenerator(null, 0); } } } return(storeResultType); }
internal FunctionColumnMapGenerator(FunctionImportMappingNonComposable mapping, int resultSetIndex, EntitySet entitySet, StructuralType baseStructuralType) { _mapping = mapping; _entitySet = entitySet; _baseStructuralType = baseStructuralType; _resultSetIndex = resultSetIndex; }
private TypeUsage DetermineStoreResultType( FunctionImportMappingNonComposable mapping, int resultSetIndex, out EntityCommandDefinition.IColumnMapGenerator columnMapGenerator) { EdmFunction functionImport = mapping.FunctionImport; StructuralType returnType; TypeUsage type; if (MetadataHelper.TryGetFunctionImportReturnType <StructuralType>(functionImport, resultSetIndex, out returnType)) { EntityCommandDefinition.ValidateEdmResultType((EdmType)returnType, functionImport); EntitySet entitySet = functionImport.EntitySets.Count > resultSetIndex ? functionImport.EntitySets[resultSetIndex] : (EntitySet)null; columnMapGenerator = (EntityCommandDefinition.IColumnMapGenerator) new EntityCommandDefinition.FunctionColumnMapGenerator(mapping, resultSetIndex, entitySet, returnType, this._columnMapFactory); type = mapping.GetExpectedTargetResultType(resultSetIndex); } else { FunctionParameter returnParameter = MetadataHelper.GetReturnParameter(functionImport, resultSetIndex); if (returnParameter != null && returnParameter.TypeUsage != null) { type = returnParameter.TypeUsage; ScalarColumnMap scalarColumnMap = new ScalarColumnMap(((CollectionType)type.EdmType).TypeUsage, string.Empty, 0, 0); SimpleCollectionColumnMap collectionColumnMap = new SimpleCollectionColumnMap(type, string.Empty, (ColumnMap)scalarColumnMap, (SimpleColumnMap[])null, (SimpleColumnMap[])null); columnMapGenerator = (EntityCommandDefinition.IColumnMapGenerator) new EntityCommandDefinition.ConstantColumnMapGenerator((ColumnMap)collectionColumnMap, 1); } else { type = (TypeUsage)null; columnMapGenerator = (EntityCommandDefinition.IColumnMapGenerator) new EntityCommandDefinition.ConstantColumnMapGenerator((ColumnMap)null, 0); } } return(type); }
// <summary> // Creates a column map for the given reader and function mapping. // </summary> internal virtual CollectionColumnMap CreateFunctionImportStructuralTypeColumnMap( DbDataReader storeDataReader, FunctionImportMappingNonComposable mapping, int resultSetIndex, EntitySet entitySet, StructuralType baseStructuralType) { var resultMapping = mapping.GetResultMapping(resultSetIndex); Debug.Assert(resultMapping != null); if (resultMapping.NormalizedEntityTypeMappings.Count == 0) // no explicit mapping; use default non-polymorphic reader { // if there is no mapping, create default mapping to root entity type or complex type Debug.Assert(!baseStructuralType.Abstract, "mapping loader must verify abstract types have explicit mapping"); return(CreateColumnMapFromReaderAndType( storeDataReader, baseStructuralType, entitySet, resultMapping.ReturnTypeColumnsRenameMapping)); } // the section below deals with the polymorphic entity type mapping for return type var baseEntityType = baseStructuralType as EntityType; Debug.Assert(null != baseEntityType, "We should have entity type here"); // Generate column maps for all discriminators var discriminatorColumns = CreateDiscriminatorColumnMaps(storeDataReader, mapping, resultSetIndex); // Generate default maps for all mapped entity types var mappedEntityTypes = new HashSet <EntityType>(resultMapping.MappedEntityTypes); mappedEntityTypes.Add(baseEntityType); // make sure the base type is represented var typeChoices = new Dictionary <EntityType, TypedColumnMap>(mappedEntityTypes.Count); ColumnMap[] baseTypeColumnMaps = null; foreach (var entityType in mappedEntityTypes) { var propertyColumnMaps = GetColumnMapsForType(storeDataReader, entityType, resultMapping.ReturnTypeColumnsRenameMapping); var entityColumnMap = CreateEntityTypeElementColumnMap( storeDataReader, entityType, entitySet, propertyColumnMaps, resultMapping.ReturnTypeColumnsRenameMapping); if (!entityType.Abstract) { typeChoices.Add(entityType, entityColumnMap); } if (entityType == baseStructuralType) { baseTypeColumnMaps = propertyColumnMaps; } } // NOTE: We don't have a null sentinel here, because the stored proc won't // return one anyway; we'll just presume the data's always there. var polymorphicMap = new MultipleDiscriminatorPolymorphicColumnMap( TypeUsage.Create(baseStructuralType), baseStructuralType.Name, baseTypeColumnMaps, discriminatorColumns, typeChoices, (object[] discriminatorValues) => mapping.Discriminate(discriminatorValues, resultSetIndex)); CollectionColumnMap collection = new SimpleCollectionColumnMap( baseStructuralType.GetCollectionType().TypeUsage, baseStructuralType.Name, polymorphicMap, null, null); return(collection); }
public void WriteFunctionImportMappingElement( FunctionImportMappingNonComposable functionImportMapping) { this.WriteFunctionImportMappingStartElement((FunctionImportMapping)functionImportMapping); foreach (FunctionImportResultMapping resultMapping in functionImportMapping.ResultMappings) { this.WriteFunctionImportResultMappingElement(resultMapping); } this.WriteFunctionImportEndElement(); }
public void WriteFunctionImportMappingElement(FunctionImportMappingNonComposable functionImportMapping) { DebugCheck.NotNull(functionImportMapping); WriteFunctionImportMappingStartElement(functionImportMapping); foreach (var resultMapping in functionImportMapping.ResultMappings) { WriteFunctionImportResultMappingElement(resultMapping); } WriteFunctionImportEndElement(); }
internal FunctionColumnMapGenerator( FunctionImportMappingNonComposable mapping, int resultSetIndex, EntitySet entitySet, StructuralType baseStructuralType, ColumnMapFactory columnMapFactory) { this._mapping = mapping; this._entitySet = entitySet; this._baseStructuralType = baseStructuralType; this._resultSetIndex = resultSetIndex; this._columnMapFactory = columnMapFactory; }
private static ScalarColumnMap[] CreateDiscriminatorColumnMaps( DbDataReader storeDataReader, FunctionImportMappingNonComposable mapping, int resultIndex) { TypeUsage type = TypeUsage.Create((EdmType)MetadataItem.EdmProviderManifest.GetPrimitiveType(PrimitiveTypeKind.String)); IList <string> discriminatorColumns = mapping.GetDiscriminatorColumns(resultIndex); ScalarColumnMap[] scalarColumnMapArray = new ScalarColumnMap[discriminatorColumns.Count]; for (int index = 0; index < scalarColumnMapArray.Length; ++index) { string str = discriminatorColumns[index]; ScalarColumnMap scalarColumnMap = new ScalarColumnMap(type, str, 0, ColumnMapFactory.GetDiscriminatorOrdinalFromReader(storeDataReader, str, mapping.FunctionImport)); scalarColumnMapArray[index] = scalarColumnMap; } return(scalarColumnMapArray); }
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); }
internal virtual CollectionColumnMap CreateFunctionImportStructuralTypeColumnMap( DbDataReader storeDataReader, FunctionImportMappingNonComposable mapping, int resultSetIndex, EntitySet entitySet, StructuralType baseStructuralType) { FunctionImportStructuralTypeMappingKB resultMapping = mapping.GetResultMapping(resultSetIndex); if (resultMapping.NormalizedEntityTypeMappings.Count == 0) { return(this.CreateColumnMapFromReaderAndType(storeDataReader, (EdmType)baseStructuralType, entitySet, resultMapping.ReturnTypeColumnsRenameMapping)); } EntityType entityType = baseStructuralType as EntityType; ScalarColumnMap[] discriminatorColumnMaps = ColumnMapFactory.CreateDiscriminatorColumnMaps(storeDataReader, mapping, resultSetIndex); HashSet <EntityType> entityTypeSet = new HashSet <EntityType>((IEnumerable <EntityType>)resultMapping.MappedEntityTypes); entityTypeSet.Add(entityType); Dictionary <EntityType, TypedColumnMap> typeChoices = new Dictionary <EntityType, TypedColumnMap>(entityTypeSet.Count); ColumnMap[] baseTypeColumns = (ColumnMap[])null; foreach (EntityType key in entityTypeSet) { ColumnMap[] columnMapsForType = ColumnMapFactory.GetColumnMapsForType(storeDataReader, (EdmType)key, resultMapping.ReturnTypeColumnsRenameMapping); EntityColumnMap elementColumnMap = ColumnMapFactory.CreateEntityTypeElementColumnMap(storeDataReader, (EdmType)key, entitySet, columnMapsForType, resultMapping.ReturnTypeColumnsRenameMapping); if (!key.Abstract) { typeChoices.Add(key, (TypedColumnMap)elementColumnMap); } if (key == baseStructuralType) { baseTypeColumns = columnMapsForType; } } MultipleDiscriminatorPolymorphicColumnMap polymorphicColumnMap = new MultipleDiscriminatorPolymorphicColumnMap(TypeUsage.Create((EdmType)baseStructuralType), baseStructuralType.Name, baseTypeColumns, (SimpleColumnMap[])discriminatorColumnMaps, typeChoices, (Func <object[], EntityType>)(discriminatorValues => mapping.Discriminate(discriminatorValues, resultSetIndex))); return((CollectionColumnMap) new SimpleCollectionColumnMap(baseStructuralType.GetCollectionType().TypeUsage, baseStructuralType.Name, (ColumnMap)polymorphicColumnMap, (SimpleColumnMap[])null, (SimpleColumnMap[])null)); }
private static ScalarColumnMap[] CreateDiscriminatorColumnMaps( DbDataReader storeDataReader, FunctionImportMappingNonComposable mapping, int resultIndex) { // choose an arbitrary type for discriminator columns -- the type is not // actually statically known EdmType discriminatorType = MetadataItem.EdmProviderManifest.GetPrimitiveType(PrimitiveTypeKind.String); var discriminatorTypeUsage = TypeUsage.Create(discriminatorType); var discriminatorColumnNames = mapping.GetDiscriminatorColumns(resultIndex); var discriminatorColumns = new ScalarColumnMap[discriminatorColumnNames.Count]; for (var i = 0; i < discriminatorColumns.Length; i++) { var columnName = discriminatorColumnNames[i]; var columnMap = new ScalarColumnMap( discriminatorTypeUsage, columnName, 0, GetDiscriminatorOrdinalFromReader(storeDataReader, columnName, mapping.FunctionImport)); discriminatorColumns[i] = columnMap; } return(discriminatorColumns); }
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 WriteFunctionImportMappingElement_does_not_write_result_mapping_for_non_composable_functions_mapped_implicitly() { var typeUsage = TypeUsage.CreateDefaultTypeUsage(PrimitiveType.GetEdmPrimitiveType(PrimitiveTypeKind.Int32)); var complexTypeProperty1 = new EdmProperty("CTProperty1", typeUsage); var complexTypeProperty2 = new EdmProperty("CTProperty2", typeUsage); var complexType = new ComplexType("CT", "Ns", DataSpace.CSpace); complexType.AddMember(complexTypeProperty1); complexType.AddMember(complexTypeProperty2); var functionImport = new EdmFunction( "f_c", "Ns", DataSpace.CSpace, new EdmFunctionPayload { IsComposable = false, IsFunctionImport = true, ReturnParameters = new[] { new FunctionParameter( "ReturnValue", TypeUsage.CreateDefaultTypeUsage(complexType.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 functionImportMapping = new FunctionImportMappingNonComposable( functionImport, storeFunction, new FunctionImportResultMapping[0], new EntityContainerMapping(new EntityContainer("C", DataSpace.SSpace))); var fixture = new Fixture(); fixture.Writer.WriteFunctionImportMappingElement(functionImportMapping); Assert.Equal( @"<FunctionImportMapping FunctionName=""Ns.Store.f_s"" FunctionImportName=""f_c"" />", fixture.ToString()); }
/// <summary> /// don't let this be constructed publicly; /// </summary> /// <exception cref="EntityCommandCompilationException">Cannot prepare the command definition for execution; consult the InnerException for more information.</exception> /// <exception cref="NotSupportedException">The ADO.NET Data Provider you are using does not support CommandTrees.</exception> internal EntityCommandDefinition(DbProviderFactory storeProviderFactory, DbCommandTree commandTree) { EntityUtil.CheckArgumentNull(storeProviderFactory, "storeProviderFactory"); EntityUtil.CheckArgumentNull(commandTree, "commandTree"); DbProviderServices storeProviderServices = DbProviderServices.GetProviderServices(storeProviderFactory); try { if (DbCommandTreeKind.Query == commandTree.CommandTreeKind) { // Next compile the plan for the command tree List <ProviderCommandInfo> mappedCommandList = new List <ProviderCommandInfo>(); ColumnMap columnMap; int columnCount; PlanCompiler.Compile(commandTree, out mappedCommandList, out columnMap, out columnCount, out _entitySets); _columnMapGenerators = new IColumnMapGenerator[] { new ConstantColumnMapGenerator(columnMap, columnCount) }; // Note: we presume that the first item in the ProviderCommandInfo is the root node; Debug.Assert(mappedCommandList.Count > 0, "empty providerCommandInfo collection and no exception?"); // this shouldn't ever happen. // Then, generate the store commands from the resulting command tree(s) _mappedCommandDefinitions = new List <DbCommandDefinition>(mappedCommandList.Count); foreach (ProviderCommandInfo providerCommandInfo in mappedCommandList) { DbCommandDefinition providerCommandDefinition = storeProviderServices.CreateCommandDefinition(providerCommandInfo.CommandTree); if (null == providerCommandDefinition) { throw EntityUtil.ProviderIncompatible(System.Data.Entity.Strings.ProviderReturnedNullForCreateCommandDefinition); } _mappedCommandDefinitions.Add(providerCommandDefinition); } } else { Debug.Assert(DbCommandTreeKind.Function == commandTree.CommandTreeKind, "only query and function command trees are supported"); DbFunctionCommandTree entityCommandTree = (DbFunctionCommandTree)commandTree; // Retrieve mapping and metadata information for the function import. FunctionImportMappingNonComposable mapping = GetTargetFunctionMapping(entityCommandTree); IList <FunctionParameter> returnParameters = entityCommandTree.EdmFunction.ReturnParameters; int resultSetCount = returnParameters.Count > 1 ? returnParameters.Count : 1; _columnMapGenerators = new IColumnMapGenerator[resultSetCount]; TypeUsage storeResultType = DetermineStoreResultType(entityCommandTree.MetadataWorkspace, mapping, 0, out _columnMapGenerators[0]); for (int i = 1; i < resultSetCount; i++) { DetermineStoreResultType(entityCommandTree.MetadataWorkspace, mapping, i, out _columnMapGenerators[i]); } // Copy over parameters (this happens through a more indirect route in the plan compiler, but // it happens nonetheless) List <KeyValuePair <string, TypeUsage> > providerParameters = new List <KeyValuePair <string, TypeUsage> >(); foreach (KeyValuePair <string, TypeUsage> parameter in entityCommandTree.Parameters) { providerParameters.Add(parameter); } // Construct store command tree usage. DbFunctionCommandTree providerCommandTree = new DbFunctionCommandTree(entityCommandTree.MetadataWorkspace, DataSpace.SSpace, mapping.TargetFunction, storeResultType, providerParameters); DbCommandDefinition storeCommandDefinition = storeProviderServices.CreateCommandDefinition(providerCommandTree); _mappedCommandDefinitions = new List <DbCommandDefinition>(1) { storeCommandDefinition }; EntitySet firstResultEntitySet = mapping.FunctionImport.EntitySets.FirstOrDefault(); if (firstResultEntitySet != null) { _entitySets = new Set <EntitySet>(); _entitySets.Add(mapping.FunctionImport.EntitySets.FirstOrDefault()); _entitySets.MakeReadOnly(); } } // Finally, build a list of the parameters that the resulting command should have; List <EntityParameter> parameterList = new List <EntityParameter>(); foreach (KeyValuePair <string, TypeUsage> queryParameter in commandTree.Parameters) { EntityParameter parameter = CreateEntityParameterFromQueryParameter(queryParameter); parameterList.Add(parameter); } _parameters = new System.Collections.ObjectModel.ReadOnlyCollection <EntityParameter>(parameterList); } catch (EntityCommandCompilationException) { // No need to re-wrap EntityCommandCompilationException throw; } catch (Exception e) { // we should not be wrapping all exceptions if (EntityUtil.IsCatchableExceptionType(e)) { // we don't wan't folks to have to know all the various types of exceptions that can // occur, so we just rethrow a CommandDefinitionException and make whatever we caught // the inner exception of it. throw EntityUtil.CommandCompilation(System.Data.Entity.Strings.EntityClient_CommandDefinitionPreparationFailed, e); } throw; } }
internal EntityCommandDefinition( DbProviderFactory storeProviderFactory, DbCommandTree commandTree, DbInterceptionContext interceptionContext, IDbDependencyResolver resolver = null, BridgeDataReaderFactory bridgeDataReaderFactory = null, ColumnMapFactory columnMapFactory = null) { this._bridgeDataReaderFactory = bridgeDataReaderFactory ?? new BridgeDataReaderFactory((Translator)null); this._columnMapFactory = columnMapFactory ?? new ColumnMapFactory(); this._storeProviderServices = (resolver != null ? resolver.GetService <DbProviderServices>((object)storeProviderFactory.GetProviderInvariantName()) : (DbProviderServices)null) ?? storeProviderFactory.GetProviderServices(); try { if (commandTree.CommandTreeKind == DbCommandTreeKind.Query) { List <ProviderCommandInfo> providerCommands = new List <ProviderCommandInfo>(); ColumnMap resultColumnMap; int columnCount; System.Data.Entity.Core.Query.PlanCompiler.PlanCompiler.Compile(commandTree, out providerCommands, out resultColumnMap, out columnCount, out this._entitySets); this._columnMapGenerators = new EntityCommandDefinition.IColumnMapGenerator[1] { (EntityCommandDefinition.IColumnMapGenerator) new EntityCommandDefinition.ConstantColumnMapGenerator(resultColumnMap, columnCount) }; this._mappedCommandDefinitions = new List <DbCommandDefinition>(providerCommands.Count); foreach (ProviderCommandInfo providerCommandInfo in providerCommands) { DbCommandDefinition commandDefinition = this._storeProviderServices.CreateCommandDefinition(providerCommandInfo.CommandTree, interceptionContext); if (commandDefinition == null) { throw new ProviderIncompatibleException(Strings.ProviderReturnedNullForCreateCommandDefinition); } this._mappedCommandDefinitions.Add(commandDefinition); } } else { DbFunctionCommandTree functionCommandTree = (DbFunctionCommandTree)commandTree; FunctionImportMappingNonComposable targetFunctionMapping = EntityCommandDefinition.GetTargetFunctionMapping(functionCommandTree); IList <FunctionParameter> returnParameters = (IList <FunctionParameter>)functionCommandTree.EdmFunction.ReturnParameters; int length = returnParameters.Count > 1 ? returnParameters.Count : 1; this._columnMapGenerators = new EntityCommandDefinition.IColumnMapGenerator[length]; TypeUsage storeResultType = this.DetermineStoreResultType(targetFunctionMapping, 0, out this._columnMapGenerators[0]); for (int resultSetIndex = 1; resultSetIndex < length; ++resultSetIndex) { this.DetermineStoreResultType(targetFunctionMapping, resultSetIndex, out this._columnMapGenerators[resultSetIndex]); } List <KeyValuePair <string, TypeUsage> > keyValuePairList = new List <KeyValuePair <string, TypeUsage> >(); foreach (KeyValuePair <string, TypeUsage> parameter in functionCommandTree.Parameters) { keyValuePairList.Add(parameter); } this._mappedCommandDefinitions = new List <DbCommandDefinition>(1) { this._storeProviderServices.CreateCommandDefinition((DbCommandTree) new DbFunctionCommandTree(functionCommandTree.MetadataWorkspace, DataSpace.SSpace, targetFunctionMapping.TargetFunction, storeResultType, (IEnumerable <KeyValuePair <string, TypeUsage> >)keyValuePairList)) }; if (targetFunctionMapping.FunctionImport.EntitySets.FirstOrDefault <EntitySet>() != null) { this._entitySets = new Set <EntitySet>(); this._entitySets.Add(targetFunctionMapping.FunctionImport.EntitySets.FirstOrDefault <EntitySet>()); this._entitySets.MakeReadOnly(); } } List <EntityParameter> entityParameterList = new List <EntityParameter>(); foreach (KeyValuePair <string, TypeUsage> parameter in commandTree.Parameters) { EntityParameter fromQueryParameter = EntityCommandDefinition.CreateEntityParameterFromQueryParameter(parameter); entityParameterList.Add(fromQueryParameter); } this._parameters = new ReadOnlyCollection <EntityParameter>((IList <EntityParameter>)entityParameterList); } catch (EntityCommandCompilationException ex) { throw; } catch (Exception ex) { if (ex.IsCatchableExceptionType()) { throw new EntityCommandCompilationException(Strings.EntityClient_CommandDefinitionPreparationFailed, ex); } throw; } }