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); }
private DbCommand PrepareEntityCommandBeforeExecution(EntityCommand entityCommand) { if (1 != this._mappedCommandDefinitions.Count) { throw new NotSupportedException("MARS"); } EntityTransaction entityTransaction = entityCommand.ValidateAndGetEntityTransaction(); InterceptableDbCommand interceptableDbCommand = new InterceptableDbCommand(this._mappedCommandDefinitions[0].CreateCommand(), entityCommand.InterceptionContext, (DbDispatchers)null); CommandHelper.SetStoreProviderCommandState(entityCommand, entityTransaction, (DbCommand)interceptableDbCommand); bool flag = false; if (interceptableDbCommand.Parameters != null) { foreach (DbParameter parameter in interceptableDbCommand.Parameters) { int index = entityCommand.Parameters.IndexOf(parameter.ParameterName); if (-1 != index) { EntityCommandDefinition.SyncParameterProperties(entityCommand.Parameters[index], parameter, this._storeProviderServices); if (parameter.Direction != ParameterDirection.Input) { flag = true; } } } } if (flag) { entityCommand.SetStoreProviderCommand((DbCommand)interceptableDbCommand); } return((DbCommand)interceptableDbCommand); }
private static EntityParameter CreateEntityParameterFromQueryParameter( KeyValuePair <string, TypeUsage> queryParameter) { EntityParameter parameter = new EntityParameter(); parameter.ParameterName = queryParameter.Key; EntityCommandDefinition.PopulateParameterFromTypeUsage(parameter, queryParameter.Value, false); return(parameter); }
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; } }
// <summary> // Gets an entitycommanddefinition from cache if a match is found for the given cache key. // </summary> // <param name="entityCommandDefinition"> out param. returns the entitycommanddefinition for a given cache key </param> // <returns> true if a match is found in cache, false otherwise </returns> private bool TryGetEntityCommandDefinitionFromQueryCache(out EntityCommandDefinition entityCommandDefinition) { Debug.Assert(null != _connection, "Connection must not be null at this point"); entityCommandDefinition = null; // if EnableQueryCaching is false, then just return to force the CommandDefinition to be created if (!_enableQueryPlanCaching || string.IsNullOrEmpty(_esqlCommandText)) { return false; } // Create cache key var queryCacheKey = new EntityClientCacheKey(this); // Try cache lookup var queryCacheManager = _connection.GetMetadataWorkspace().GetQueryCacheManager(); Debug.Assert(null != queryCacheManager, "QuerycacheManager instance cannot be null"); if (!queryCacheManager.TryCacheLookup(queryCacheKey, out entityCommandDefinition)) { // if not, construct the command definition using no special options; entityCommandDefinition = CreateCommandDefinition(); // add to the cache QueryCacheEntry outQueryCacheEntry = null; if (queryCacheManager.TryLookupAndAdd(new QueryCacheEntry(queryCacheKey, entityCommandDefinition), out outQueryCacheEntry)) { entityCommandDefinition = (EntityCommandDefinition)outQueryCacheEntry.GetTarget(); } } Debug.Assert(null != entityCommandDefinition, "out entityCommandDefinition must not be null"); return true; }
// <summary> // Get the command definition for the command; will construct one if there is not already // one constructed, which means it will prepare the command on the client. // </summary> // <returns> the command definition </returns> internal virtual EntityCommandDefinition GetCommandDefinition() { var entityCommandDefinition = _commandDefinition; // Construct the command definition using no special options; if (null == entityCommandDefinition) { // check if the _commandDefinition is in cache if (!TryGetEntityCommandDefinitionFromQueryCache(out entityCommandDefinition)) { // if not, construct the command definition using no special options; entityCommandDefinition = CreateCommandDefinition(); } _commandDefinition = entityCommandDefinition; } return entityCommandDefinition; }
// <summary> // Creates a prepared version of this command without regard to the current connection state. // Called by both <see cref="Prepare" /> and <see cref="ToTraceString" />. // </summary> private void InnerPrepare() { // Unprepare if the parameters have changed to force a reprepare if (_parameters.IsDirty) { Unprepare(); } _commandDefinition = GetCommandDefinition(); Debug.Assert(null != _commandDefinition, "_commandDefinition cannot be null"); }
// <summary> // Clear out any "compile" state // </summary> internal virtual void Unprepare() { _commandDefinition = null; _preparedCommandTree = null; // Clear the dirty flag on the parameters and parameter collection _parameters.ResetIsDirty(); }
// <summary> // Constructs a new EntityCommand given a EntityConnection and an EntityCommandDefition. This // constructor is used by ObjectQueryExecution plan to execute an ObjectQuery. // </summary> // <param name="connection"> The connection against which this EntityCommand should execute </param> // <param name="entityCommandDefinition"> The prepared command definition that can be executed using this EntityCommand </param> internal EntityCommand( EntityConnection connection, EntityCommandDefinition entityCommandDefinition, DbInterceptionContext context, EntityDataReaderFactory factory = null) : this(entityCommandDefinition, context, factory) { _connection = connection; }
// <summary> // Internal constructor used by EntityCommandDefinition // </summary> // <param name="commandDefinition"> The prepared command definition that can be executed using this EntityCommand </param> internal EntityCommand(EntityCommandDefinition commandDefinition, DbInterceptionContext context, EntityDataReaderFactory factory = null) : this(context, factory) { // Assign other member fields from the parameters _commandDefinition = commandDefinition; _parameters = new EntityParameterCollection(); // Make copies of the parameters foreach (var parameter in commandDefinition.Parameters) { _parameters.Add(parameter.Clone()); } // Reset the dirty flag that was set to true when the parameters were added so that it won't say // it's dirty to start with _parameters.ResetIsDirty(); // Track the fact that this command was created from and represents an already prepared command definition _isCommandDefinitionBased = true; }