/// <summary> /// Constructor for testing/mocking purposes. /// </summary> protected EntityCommandDefinition( BridgeDataReaderFactory factory = null, ColumnMapFactory columnMapFactory = null, List <DbCommandDefinition> mappedCommandDefinitions = null) { _bridgeDataReaderFactory = factory ?? new BridgeDataReaderFactory(); _columnMapFactory = columnMapFactory ?? new ColumnMapFactory(); _mappedCommandDefinitions = mappedCommandDefinitions; }
internal EntityCommandDefinition( DbProviderFactory storeProviderFactory, DbCommandTree commandTree, IDbDependencyResolver resolver = null, BridgeDataReaderFactory bridgeDataReaderFactory = null, ColumnMapFactory columnMapFactory = null) { DebugCheck.NotNull(storeProviderFactory); DebugCheck.NotNull(commandTree); _bridgeDataReaderFactory = bridgeDataReaderFactory ?? new BridgeDataReaderFactory(); _columnMapFactory = columnMapFactory ?? new ColumnMapFactory(); _storeProviderServices = (resolver != null ? resolver.GetService <DbProviderServices>(storeProviderFactory.GetProviderInvariantName()) : null) ?? storeProviderFactory.GetProviderServices(); try { if (DbCommandTreeKind.Query == commandTree.CommandTreeKind) { // Next compile the plan for the command tree var 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 (var providerCommandInfo in mappedCommandList) { var providerCommandDefinition = _storeProviderServices.CreateCommandDefinition(providerCommandInfo.CommandTree); if (null == providerCommandDefinition) { throw new ProviderIncompatibleException(Strings.ProviderReturnedNullForCreateCommandDefinition); } _mappedCommandDefinitions.Add(providerCommandDefinition); } } else { Debug.Assert( DbCommandTreeKind.Function == commandTree.CommandTreeKind, "only query and function command trees are supported"); var entityCommandTree = (DbFunctionCommandTree)commandTree; // Retrieve mapping and metadata information for the function import. var mapping = GetTargetFunctionMapping(entityCommandTree); IList <FunctionParameter> returnParameters = entityCommandTree.EdmFunction.ReturnParameters; var resultSetCount = returnParameters.Count > 1 ? returnParameters.Count : 1; _columnMapGenerators = new IColumnMapGenerator[resultSetCount]; var storeResultType = DetermineStoreResultType(mapping, 0, out _columnMapGenerators[0]); for (var i = 1; i < resultSetCount; i++) { DetermineStoreResultType(mapping, i, out _columnMapGenerators[i]); } // Copy over parameters (this happens through a more indirect route in the plan compiler, but // it happens nonetheless) var providerParameters = new List <KeyValuePair <string, TypeUsage> >(); foreach (var parameter in entityCommandTree.Parameters) { providerParameters.Add(parameter); } // Construct store command tree usage. var providerCommandTree = new DbFunctionCommandTree( entityCommandTree.MetadataWorkspace, DataSpace.SSpace, mapping.TargetFunction, storeResultType, providerParameters); var storeCommandDefinition = _storeProviderServices.CreateCommandDefinition(providerCommandTree); _mappedCommandDefinitions = new List <DbCommandDefinition>(1) { storeCommandDefinition }; var 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; var parameterList = new List <EntityParameter>(); foreach (var queryParameter in commandTree.Parameters) { var parameter = CreateEntityParameterFromQueryParameter(queryParameter); parameterList.Add(parameter); } _parameters = new ReadOnlyCollection <EntityParameter>(parameterList); } catch (EntityCommandCompilationException) { // No need to re-wrap EntityCommandCompilationException throw; } catch (Exception e) { // we should not be wrapping all exceptions if (e.IsCatchableExceptionType()) { // 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 new EntityCommandCompilationException(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; } }