private static ObjectParameterCollection MergeParameters( ObjectParameterCollection query1Params, ObjectParameterCollection query2Params) { if (query1Params == null && query2Params == null) { return((ObjectParameterCollection)null); } ObjectParameterCollection parameterCollection1; ObjectParameterCollection parameterCollection2; if (query1Params != null) { parameterCollection1 = ObjectParameterCollection.DeepCopy(query1Params); parameterCollection2 = query2Params; } else { parameterCollection1 = ObjectParameterCollection.DeepCopy(query2Params); parameterCollection2 = query1Params; } if (parameterCollection2 != null) { foreach (ObjectParameter objectParameter in parameterCollection2) { parameterCollection1.Add(objectParameter.ShallowCopy()); } } return(parameterCollection1); }
public void Remove_throws_for_null_argument() { var objectParameterCollection = new ObjectParameterCollection(new ClrPerspective(new MetadataWorkspace())); Assert.Equal("item", Assert.Throws<ArgumentNullException>( () => objectParameterCollection.Remove(null)).ParamName); }
internal static ObjectQueryState OfType(ObjectQueryState query, EdmType newType, Type clrOfType) { Debug.Assert(newType != null, "OfType cannot be null"); Debug.Assert(Helper.IsEntityType(newType) || Helper.IsComplexType(newType), "OfType must be Entity or Complex type"); string queryText = GetCommandText(query); // Build the new query string - "OFTYPE((<query>), [<type namespace>].[<type name>])" int queryLength = _ofTypeProlog.Length + queryText.Length + _ofTypeInfix.Length + newType.NamespaceName.Length + (newType.NamespaceName != string.Empty ? _ofTypeInfix2.Length : 0) + newType.Name.Length + _ofTypeEpilog.Length; StringBuilder builder = new StringBuilder(queryLength); builder.Append(_ofTypeProlog); builder.Append(queryText); builder.Append(_ofTypeInfix); if (newType.NamespaceName != string.Empty) { builder.Append(newType.NamespaceName); builder.Append(_ofTypeInfix2); } builder.Append(newType.Name); builder.Append(_ofTypeEpilog); // Create a new EntitySqlQueryImplementation that uses the new query as its command text. // Span is carried over, no adjustment is needed return(NewBuilderQuery(query, clrOfType, builder, query.Span, ObjectParameterCollection.DeepCopy(query.Parameters))); }
/// <summary> /// Merges <see cref="ObjectParameter"/>s from two ObjectQuery arguments to SetOp builder methods (Except, Intersect, Union, UnionAll). /// A new <see cref="ObjectParameterCollection"/> is returned that contains copies of parameters from both <paramref name="query1Params"/> and <paramref name="query2Params"/>. /// </summary> /// <param name="query1Params">ObjectParameters from the first ObjectQuery argument (on which the query builder method was called)</param> /// <param name="query2Params">ObjectParameters from the second ObjectQuery argument (specified as an argument to the builder method)</param> /// <returns>A new ObjectParameterCollection containing copies of all parameters</returns> private static ObjectParameterCollection MergeParameters(ObjectParameterCollection query1Params, ObjectParameterCollection query2Params) { if (query1Params == null && query2Params == null) { return null; } ObjectParameterCollection mergedParams; ObjectParameterCollection sourceParams; if (query1Params != null) { mergedParams = ObjectParameterCollection.DeepCopy(query1Params); sourceParams = query2Params; } else { mergedParams = ObjectParameterCollection.DeepCopy(query2Params); sourceParams = query1Params; } if (sourceParams != null) { foreach (ObjectParameter sourceParam in sourceParams) { mergedParams.Add(sourceParam.ShallowCopy()); } } return mergedParams; }
private EntityCommand PrepareEntityCommand( ObjectContext context, ObjectParameterCollection parameterValues) { EntityCommandDefinition commandDefinition = (EntityCommandDefinition)this.CommandDefinition; EntityConnection connection = (EntityConnection)context.Connection; EntityCommand entityCommand = new EntityCommand(connection, commandDefinition, context.InterceptionContext, (EntityCommand.EntityDataReaderFactory)null); if (context.CommandTimeout.HasValue) { entityCommand.CommandTimeout = context.CommandTimeout.Value; } if (parameterValues != null) { foreach (ObjectParameter parameterValue in parameterValues) { int index = entityCommand.Parameters.IndexOf(parameterValue.Name); if (index != -1) { entityCommand.Parameters[index].Value = parameterValue.Value ?? (object)DBNull.Value; } } } if (connection.CurrentTransaction != null) { entityCommand.Transaction = connection.CurrentTransaction; } return(entityCommand); }
private EntityCommand PrepareEntityCommand(ObjectContext context, ObjectParameterCollection parameterValues) { // create entity command (just do this to snarf store command) var commandDefinition = (EntityCommandDefinition)CommandDefinition; var entityCommand = new EntityCommand( (EntityConnection)context.Connection, commandDefinition, context.InterceptionContext); // pass through parameters and timeout values if (context.CommandTimeout.HasValue) { entityCommand.CommandTimeout = context.CommandTimeout.Value; } if (parameterValues != null) { foreach (var parameter in parameterValues) { var index = entityCommand.Parameters.IndexOf(parameter.Name); if (index != -1) { entityCommand.Parameters[index].Value = parameter.Value ?? DBNull.Value; } } } return(entityCommand); }
/// <summary> /// Merges <see cref="ObjectParameter"/>s from two ObjectQuery arguments to SetOp builder methods (Except, Intersect, Union, UnionAll). /// A new <see cref="ObjectParameterCollection"/> is returned that contains copies of parameters from both <paramref name="query1Params"/> and <paramref name="query2Params"/>. /// </summary> /// <param name="query1Params">ObjectParameters from the first ObjectQuery argument (on which the query builder method was called)</param> /// <param name="query2Params">ObjectParameters from the second ObjectQuery argument (specified as an argument to the builder method)</param> /// <returns>A new ObjectParameterCollection containing copies of all parameters</returns> private static ObjectParameterCollection MergeParameters(ObjectParameterCollection query1Params, ObjectParameterCollection query2Params) { if (query1Params == null && query2Params == null) { return(null); } ObjectParameterCollection mergedParams; ObjectParameterCollection sourceParams; if (query1Params != null) { mergedParams = ObjectParameterCollection.DeepCopy(query1Params); sourceParams = query2Params; } else { mergedParams = ObjectParameterCollection.DeepCopy(query2Params); sourceParams = query1Params; } if (sourceParams != null) { foreach (ObjectParameter sourceParam in sourceParams) { mergedParams.Add(sourceParam.ShallowCopy()); } } return(mergedParams); }
protected ObjectQueryState( Type elementType, ObjectContext context, ObjectParameterCollection parameters, Span span) { this._elementType = elementType; this._context = context; this._span = span; this._parameters = parameters; }
internal ObjectParameterCollection EnsureParameters() { if (this._parameters == null) { this._parameters = new ObjectParameterCollection(this.ObjectContext.Perspective); if (this._cachedPlan != null) { this._parameters.SetReadOnly(true); } } return(this._parameters); }
public static void CopyTo(this ObjectParameterCollection parameters, DbCommand command, Func <string, string> fnGetParamName = null, IBatchRunner runner = null) { fnGetParamName = fnGetParamName ?? (paramName => paramName); runner = runner ?? BatchExtensions.ResolveRunner(); var nullValue = runner.DbNull; foreach (var objectParameter in parameters) { var parameter = command.CreateParameter(); parameter.ParameterName = fnGetParamName(objectParameter.Name); parameter.Value = objectParameter.Value ?? nullValue; command.Parameters.Add(parameter); } }
internal static ObjectQueryState Distinct(ObjectQueryState query) { // Build the new query string - "SET(<this query>)" string queryText = GetCommandText(query); StringBuilder builder = new StringBuilder(_distinctProlog.Length + queryText.Length + _distinctEpilog.Length); builder.Append(_distinctProlog); builder.Append(queryText); builder.Append(_distinctEpilog); // Span is carried over, no adjustment is needed return(NewBuilderQuery(query, query.ElementType, builder, query.Span, ObjectParameterCollection.DeepCopy(query.Parameters))); }
/// <summary> /// Constructs a new <see cref="ObjectQueryState"/> instance that uses the specified context and parameters collection. /// </summary> /// <param name="context"> /// The ObjectContext to which the implemented ObjectQuery belongs /// </param> protected ObjectQueryState(Type elementType, ObjectContext context, ObjectParameterCollection parameters, Span span) { // Validate the element type EntityUtil.CheckArgumentNull(elementType, "elementType"); // Validate the context EntityUtil.CheckArgumentNull(context, "context"); // Parameters and Span are specifically allowed to be null this._elementType = elementType; this._context = context; this._span = span; this._parameters = parameters; }
// <summary> // Constructs a new <see cref="ObjectQueryState" /> instance that uses the specified context and parameters collection. // </summary> // <param name="context"> The ObjectContext to which the implemented ObjectQuery belongs </param> protected ObjectQueryState(Type elementType, ObjectContext context, ObjectParameterCollection parameters, Span span) { // Validate the element type DebugCheck.NotNull(elementType); // Validate the context DebugCheck.NotNull(context); // Parameters and Span are specifically allowed to be null _elementType = elementType; _context = context; _span = span; _parameters = parameters; }
private static ObjectParameterCollection MergeParameters( ObjectContext context, ObjectParameterCollection sourceQueryParams, ObjectParameter[] builderMethodParams) { if (sourceQueryParams == null && builderMethodParams.Length == 0) { return((ObjectParameterCollection)null); } ObjectParameterCollection parameterCollection = ObjectParameterCollection.DeepCopy(sourceQueryParams) ?? new ObjectParameterCollection(context.Perspective); foreach (ObjectParameter builderMethodParam in builderMethodParams) { parameterCollection.Add(builderMethodParam); } return(parameterCollection); }
internal virtual async Task <ObjectResult <TResultType> > ExecuteAsync <TResultType>( ObjectContext context, ObjectParameterCollection parameterValues, CancellationToken cancellationToken) { cancellationToken.ThrowIfCancellationRequested(); DbDataReader storeReader = (DbDataReader)null; BufferedDataReader bufferedReader = (BufferedDataReader)null; ObjectResult <TResultType> objectResult; try { using (EntityCommand entityCommand = this.PrepareEntityCommand(context, parameterValues)) storeReader = await entityCommand.GetCommandDefinition().ExecuteStoreCommandsAsync(entityCommand, this.Streaming ? CommandBehavior.Default : CommandBehavior.SequentialAccess, cancellationToken).WithCurrentCulture <DbDataReader>(); ShaperFactory <TResultType> shaperFactory = (ShaperFactory <TResultType>) this.ResultShaperFactory; Shaper <TResultType> shaper; if (this.Streaming) { shaper = shaperFactory.Create(storeReader, context, context.MetadataWorkspace, this.MergeOption, true, this.Streaming); } else { StoreItemCollection storeItemCollection = (StoreItemCollection)context.MetadataWorkspace.GetItemCollection(DataSpace.SSpace); DbProviderServices providerServices = DbConfiguration.DependencyResolver.GetService <DbProviderServices>((object)storeItemCollection.ProviderInvariantName); bufferedReader = new BufferedDataReader(storeReader); await bufferedReader.InitializeAsync(storeItemCollection.ProviderManifestToken, providerServices, shaperFactory.ColumnTypes, shaperFactory.NullableColumns, cancellationToken).WithCurrentCulture(); shaper = shaperFactory.Create((DbDataReader)bufferedReader, context, context.MetadataWorkspace, this.MergeOption, true, this.Streaming); } TypeUsage resultItemEdmType = this.ResultType.EdmType.BuiltInTypeKind != BuiltInTypeKind.CollectionType ? this.ResultType : ((CollectionType)this.ResultType.EdmType).TypeUsage; objectResult = new ObjectResult <TResultType>(shaper, this._singleEntitySet, resultItemEdmType); } catch (Exception ex) { if (this.Streaming && storeReader != null) { storeReader.Dispose(); } if (!this.Streaming && bufferedReader != null) { bufferedReader.Dispose(); } throw; } return(objectResult); }
private static ObjectQueryState NewBuilderQuery(ObjectQueryState sourceQuery, Type elementType, StringBuilder queryText, bool allowsLimit, Span newSpan, IEnumerable <ObjectParameter> enumerableParams) { ObjectParameterCollection queryParams = enumerableParams as ObjectParameterCollection; if (queryParams == null && enumerableParams != null) { queryParams = new ObjectParameterCollection(sourceQuery.ObjectContext.Perspective); foreach (ObjectParameter objectParam in enumerableParams) { queryParams.Add(objectParam); } } EntitySqlQueryState newState = new EntitySqlQueryState(elementType, queryText.ToString(), allowsLimit, sourceQuery.ObjectContext, queryParams, newSpan); sourceQuery.ApplySettingsTo(newState); return(newState); }
internal virtual ObjectResult <TResultType> Execute <TResultType>( ObjectContext context, ObjectParameterCollection parameterValues) { DbDataReader reader = (DbDataReader)null; BufferedDataReader bufferedDataReader = (BufferedDataReader)null; try { using (EntityCommand entityCommand = this.PrepareEntityCommand(context, parameterValues)) reader = entityCommand.GetCommandDefinition().ExecuteStoreCommands(entityCommand, this.Streaming ? CommandBehavior.Default : CommandBehavior.SequentialAccess); ShaperFactory <TResultType> resultShaperFactory = (ShaperFactory <TResultType>) this.ResultShaperFactory; Shaper <TResultType> shaper; if (this.Streaming) { shaper = resultShaperFactory.Create(reader, context, context.MetadataWorkspace, this.MergeOption, true, this.Streaming); } else { StoreItemCollection itemCollection = (StoreItemCollection)context.MetadataWorkspace.GetItemCollection(DataSpace.SSpace); DbProviderServices service = DbConfiguration.DependencyResolver.GetService <DbProviderServices>((object)itemCollection.ProviderInvariantName); bufferedDataReader = new BufferedDataReader(reader); bufferedDataReader.Initialize(itemCollection.ProviderManifestToken, service, resultShaperFactory.ColumnTypes, resultShaperFactory.NullableColumns); shaper = resultShaperFactory.Create((DbDataReader)bufferedDataReader, context, context.MetadataWorkspace, this.MergeOption, true, this.Streaming); } TypeUsage resultItemType = this.ResultType.EdmType.BuiltInTypeKind != BuiltInTypeKind.CollectionType ? this.ResultType : ((CollectionType)this.ResultType.EdmType).TypeUsage; return(new ObjectResult <TResultType>(shaper, this._singleEntitySet, resultItemType)); } catch (Exception ex) { if (this.Streaming && reader != null) { reader.Dispose(); } if (!this.Streaming && bufferedDataReader != null) { bufferedDataReader.Dispose(); } throw; } }
/// <summary> /// Merges <see cref="ObjectParameter"/>s from a source ObjectQuery with ObjectParameters specified as an argument to a builder method. /// A new <see cref="ObjectParameterCollection"/> is returned that contains copies of parameters from both <paramref name="sourceQueryParams"/> and <paramref name="builderMethodParams"/>. /// </summary> /// <param name="context">The <see cref="ObjectContext"/> to use when constructing the new parameter collection</param> /// <param name="sourceQueryParams">ObjectParameters from the ObjectQuery on which the query builder method was called</param> /// <param name="builderMethodParams">ObjectParameters that were specified as an argument to the builder method</param> /// <returns>A new ObjectParameterCollection containing copies of all parameters</returns> private static ObjectParameterCollection MergeParameters(ObjectContext context, ObjectParameterCollection sourceQueryParams, ObjectParameter[] builderMethodParams) { Debug.Assert(builderMethodParams != null, "params array argument should not be null"); if (sourceQueryParams == null && builderMethodParams.Length == 0) { return null; } ObjectParameterCollection mergedParams = ObjectParameterCollection.DeepCopy(sourceQueryParams); if (mergedParams == null) { mergedParams = new ObjectParameterCollection(context.Perspective); } foreach (ObjectParameter builderParam in builderMethodParams) { mergedParams.Add(builderParam); } return mergedParams; }
/// <summary> /// Merges <see cref="ObjectParameter"/>s from a source ObjectQuery with ObjectParameters specified as an argument to a builder method. /// A new <see cref="ObjectParameterCollection"/> is returned that contains copies of parameters from both <paramref name="sourceQueryParams"/> and <paramref name="builderMethodParams"/>. /// </summary> /// <param name="context">The <see cref="ObjectContext"/> to use when constructing the new parameter collection</param> /// <param name="sourceQueryParams">ObjectParameters from the ObjectQuery on which the query builder method was called</param> /// <param name="builderMethodParams">ObjectParameters that were specified as an argument to the builder method</param> /// <returns>A new ObjectParameterCollection containing copies of all parameters</returns> private static ObjectParameterCollection MergeParameters(ObjectContext context, ObjectParameterCollection sourceQueryParams, ObjectParameter[] builderMethodParams) { Debug.Assert(builderMethodParams != null, "params array argument should not be null"); if (sourceQueryParams == null && builderMethodParams.Length == 0) { return(null); } ObjectParameterCollection mergedParams = ObjectParameterCollection.DeepCopy(sourceQueryParams); if (mergedParams == null) { mergedParams = new ObjectParameterCollection(context.Perspective); } foreach (ObjectParameter builderParam in builderMethodParams) { mergedParams.Add(builderParam); } return(mergedParams); }
// <summary> // Merges <see cref="ObjectParameter" />s from a source ObjectQuery with ObjectParameters specified as an argument to a builder method. // A new <see cref="ObjectParameterCollection" /> is returned that contains copies of parameters from both // <paramref // name="sourceQueryParams" /> // and <paramref name="builderMethodParams" />. // </summary> // <param name="context"> // The <see cref="ObjectContext" /> to use when constructing the new parameter collection // </param> // <param name="sourceQueryParams"> ObjectParameters from the ObjectQuery on which the query builder method was called </param> // <param name="builderMethodParams"> ObjectParameters that were specified as an argument to the builder method </param> // <returns> A new ObjectParameterCollection containing copies of all parameters </returns> private static ObjectParameterCollection MergeParameters( ObjectContext context, ObjectParameterCollection sourceQueryParams, ObjectParameter[] builderMethodParams) { DebugCheck.NotNull(builderMethodParams); if (sourceQueryParams == null && builderMethodParams.Length == 0) { return null; } var mergedParams = ObjectParameterCollection.DeepCopy(sourceQueryParams); if (mergedParams == null) { mergedParams = new ObjectParameterCollection(context.Perspective); } foreach (var builderParam in builderMethodParams) { mergedParams.Add(builderParam); } return mergedParams; }
// <summary> // Merges <see cref="ObjectParameter" />s from a source ObjectQuery with ObjectParameters specified as an argument to a builder method. // A new <see cref="ObjectParameterCollection" /> is returned that contains copies of parameters from both // <paramref // name="sourceQueryParams" /> // and <paramref name="builderMethodParams" />. // </summary> // <param name="context"> // The <see cref="ObjectContext" /> to use when constructing the new parameter collection // </param> // <param name="sourceQueryParams"> ObjectParameters from the ObjectQuery on which the query builder method was called </param> // <param name="builderMethodParams"> ObjectParameters that were specified as an argument to the builder method </param> // <returns> A new ObjectParameterCollection containing copies of all parameters </returns> private static ObjectParameterCollection MergeParameters( ObjectContext context, ObjectParameterCollection sourceQueryParams, ObjectParameter[] builderMethodParams) { DebugCheck.NotNull(builderMethodParams); if (sourceQueryParams == null && builderMethodParams.Length == 0) { return(null); } var mergedParams = ObjectParameterCollection.DeepCopy(sourceQueryParams); if (mergedParams == null) { mergedParams = new ObjectParameterCollection(context.Perspective); } foreach (var builderParam in builderMethodParams) { mergedParams.Add(builderParam); } return(mergedParams); }
internal override ObjectQueryExecutionPlan GetExecutionPlan(MergeOption?forMergeOption) { Debug.Assert(this.Span == null, "Include span specified on compiled LINQ-based ObjectQuery instead of within the expression tree?"); Debug.Assert(this._cachedPlan == null, "Cached plan should not be set on compiled LINQ queries"); // Metadata is required to generate the execution plan or to retrieve it from the cache. this.ObjectContext.EnsureMetadata(); ObjectQueryExecutionPlan plan = null; CompiledQueryCacheEntry cacheEntry = this._cacheEntry; bool useCSharpNullComparisonBehavior = this.ObjectContext.ContextOptions.UseCSharpNullComparisonBehavior; if (cacheEntry != null) { // The cache entry has already been retrieved, so compute the effective merge option with the following precedence: // 1. The merge option specified as the argument to Execute(MergeOption), and so to this method // 2. The merge option set using ObjectQuery.MergeOption // 3. The propagated merge option as recorded in the cache entry // 4. The global default merge option. MergeOption mergeOption = EnsureMergeOption(forMergeOption, this.UserSpecifiedMergeOption, cacheEntry.PropagatedMergeOption); // Ask for the corresponding execution plan plan = cacheEntry.GetExecutionPlan(mergeOption, useCSharpNullComparisonBehavior); if (plan == null) { // Convert the LINQ expression to produce a command tree ExpressionConverter converter = this.CreateExpressionConverter(); DbExpression queryExpression = converter.Convert(); ReadOnlyCollection <KeyValuePair <ObjectParameter, QueryParameterExpression> > parameters = converter.GetParameters(); // Prepare the execution plan using the command tree and the computed effective merge option DbQueryCommandTree tree = DbQueryCommandTree.FromValidExpression(this.ObjectContext.MetadataWorkspace, DataSpace.CSpace, queryExpression); plan = ObjectQueryExecutionPlan.Prepare(this.ObjectContext, tree, this.ElementType, mergeOption, converter.PropagatedSpan, parameters, converter.AliasGenerator); // Update and retrieve the execution plan plan = cacheEntry.SetExecutionPlan(plan, useCSharpNullComparisonBehavior); } } else { // This instance does not yet have a reference to a cache entry. // First, attempt to retrieve an existing cache entry. QueryCacheManager cacheManager = this.ObjectContext.MetadataWorkspace.GetQueryCacheManager(); CompiledQueryCacheKey cacheKey = new CompiledQueryCacheKey(this._cacheToken); if (cacheManager.TryCacheLookup(cacheKey, out cacheEntry)) { // An entry was found in the cache, so compute the effective merge option based on its propagated merge option, // and use the UseCSharpNullComparisonBehavior flag to retrieve the corresponding execution plan. this._cacheEntry = cacheEntry; MergeOption mergeOption = EnsureMergeOption(forMergeOption, this.UserSpecifiedMergeOption, cacheEntry.PropagatedMergeOption); plan = cacheEntry.GetExecutionPlan(mergeOption, useCSharpNullComparisonBehavior); } // If no cache entry was found or if the cache entry did not contain the required execution plan, the plan is still null at this point. if (plan == null) { // The execution plan needs to be produced, so create an appropriate expression converter and generate the query command tree. ExpressionConverter converter = this.CreateExpressionConverter(); DbExpression queryExpression = converter.Convert(); ReadOnlyCollection <KeyValuePair <ObjectParameter, QueryParameterExpression> > parameters = converter.GetParameters(); DbQueryCommandTree tree = DbQueryCommandTree.FromValidExpression(this.ObjectContext.MetadataWorkspace, DataSpace.CSpace, queryExpression); // If a cache entry for this compiled query's cache key was not successfully retrieved, then it must be created now. // Note that this is only possible after converting the LINQ expression and discovering the propagated merge option, // which is required in order to create the cache entry. if (cacheEntry == null) { // Create the cache entry using this instance's cache token and the propagated merge option (which may be null) cacheEntry = new CompiledQueryCacheEntry(cacheKey, converter.PropagatedMergeOption); // Attempt to add the entry to the cache. If an entry was added in the meantime, use that entry instead. QueryCacheEntry foundEntry; if (cacheManager.TryLookupAndAdd(cacheEntry, out foundEntry)) { cacheEntry = (CompiledQueryCacheEntry)foundEntry; } // We now have a cache entry, so hold onto it for future use. this._cacheEntry = cacheEntry; } // Recompute the effective merge option in case a cache entry was just constructed above MergeOption mergeOption = EnsureMergeOption(forMergeOption, this.UserSpecifiedMergeOption, cacheEntry.PropagatedMergeOption); // Ask the (retrieved or constructed) cache entry for the corresponding execution plan. plan = cacheEntry.GetExecutionPlan(mergeOption, useCSharpNullComparisonBehavior); if (plan == null) { // The plan is not present, so prepare it now using the computed effective merge option plan = ObjectQueryExecutionPlan.Prepare(this.ObjectContext, tree, this.ElementType, mergeOption, converter.PropagatedSpan, parameters, converter.AliasGenerator); // Update the execution plan on the cache entry. // If the execution plan was set in the meantime, SetExecutionPlan will return that value, otherwise it will return 'plan'. plan = cacheEntry.SetExecutionPlan(plan, useCSharpNullComparisonBehavior); } } } // Get parameters from the plan and set them. ObjectParameterCollection currentParams = this.EnsureParameters(); if (plan.CompiledQueryParameters != null && plan.CompiledQueryParameters.Count > 0) { currentParams.SetReadOnly(false); currentParams.Clear(); foreach (KeyValuePair <ObjectParameter, QueryParameterExpression> pair in plan.CompiledQueryParameters) { // Parameters retrieved from the CompiledQueryParameters collection must be cloned before being added to the query. // The cached plan is shared and when used in multithreaded scenarios failing to clone the parameter would result // in the code below updating the values of shared parameter instances saved in the cached plan and used by all // queries using that plan, regardless of the values they were actually invoked with, causing incorrect results // when those queries were later executed. // ObjectParameter convertedParam = pair.Key.ShallowCopy(); QueryParameterExpression parameterExpression = pair.Value; currentParams.Add(convertedParam); if (parameterExpression != null) { convertedParam.Value = parameterExpression.EvaluateParameter(_parameterValues); } } } currentParams.SetReadOnly(true); Debug.Assert(plan != null, "Failed to produce an execution plan?"); return(plan); }
internal static ObjectQueryState Distinct(ObjectQueryState query) { string commandText = EntitySqlQueryBuilder.GetCommandText(query); StringBuilder queryText = new StringBuilder("SET(\r\n".Length + commandText.Length + "\r\n)".Length); queryText.Append("SET(\r\n"); queryText.Append(commandText); queryText.Append("\r\n)"); return(EntitySqlQueryBuilder.NewBuilderQuery(query, query.ElementType, queryText, query.Span, (IEnumerable <ObjectParameter>)ObjectParameterCollection.DeepCopy(query.Parameters))); }
internal static ObjectQueryState OfType( ObjectQueryState query, EdmType newType, Type clrOfType) { string commandText = EntitySqlQueryBuilder.GetCommandText(query); StringBuilder queryText = new StringBuilder("OFTYPE(\r\n(\r\n".Length + commandText.Length + "\r\n),\r\n[".Length + newType.NamespaceName.Length + (!string.IsNullOrEmpty(newType.NamespaceName) ? "].[".Length : 0) + newType.Name.Length + "]\r\n)".Length); queryText.Append("OFTYPE(\r\n(\r\n"); queryText.Append(commandText); queryText.Append("\r\n),\r\n["); if (!string.IsNullOrEmpty(newType.NamespaceName)) { queryText.Append(newType.NamespaceName); queryText.Append("].["); } queryText.Append(newType.Name); queryText.Append("]\r\n)"); return(EntitySqlQueryBuilder.NewBuilderQuery(query, clrOfType, queryText, query.Span, (IEnumerable <ObjectParameter>)ObjectParameterCollection.DeepCopy(query.Parameters))); }
internal virtual ObjectResult <TResultType> Execute <TResultType>(ObjectContext context, ObjectParameterCollection parameterValues) { DbDataReader storeReader = null; BufferedDataReader bufferedReader = null; try { using (var entityCommand = PrepareEntityCommand(context, parameterValues)) { // acquire store reader storeReader = entityCommand.GetCommandDefinition().ExecuteStoreCommands( entityCommand, Streaming ? CommandBehavior.Default : CommandBehavior.SequentialAccess); } var shaperFactory = (ShaperFactory <TResultType>)ResultShaperFactory; Shaper <TResultType> shaper; if (Streaming) { shaper = shaperFactory.Create( storeReader, context, context.MetadataWorkspace, MergeOption, true, useSpatialReader: true, shouldReleaseConnection: Streaming); } else { var storeItemCollection = (StoreItemCollection)context.MetadataWorkspace.GetItemCollection(DataSpace.SSpace); var providerServices = DbConfiguration.DependencyResolver.GetService <DbProviderServices>(storeItemCollection.StoreProviderInvariantName); bufferedReader = new BufferedDataReader(storeReader); bufferedReader.Initialize(storeItemCollection.StoreProviderManifestToken, providerServices); shaper = shaperFactory.Create( bufferedReader, context, context.MetadataWorkspace, MergeOption, true, useSpatialReader: false, shouldReleaseConnection: Streaming); } // create materializer delegate TypeUsage resultItemEdmType; if (ResultType.EdmType.BuiltInTypeKind == BuiltInTypeKind.CollectionType) { resultItemEdmType = ((CollectionType)ResultType.EdmType).TypeUsage; } else { resultItemEdmType = ResultType; } return(new ObjectResult <TResultType>(shaper, _singleEntitySet, resultItemEdmType)); } catch (Exception) { // Note: The ObjectResult is responsible for disposing the reader if creating // the enumerator fails. if (Streaming && storeReader != null) { storeReader.Dispose(); } if (!Streaming && bufferedReader != null) { bufferedReader.Dispose(); } throw; } }
private ParameterReferenceRemover(ObjectParameterCollection availableParams) { Debug.Assert(availableParams != null, "Parameter collection cannot be null"); objectParameters = availableParams; }
internal override ObjectQueryExecutionPlan GetExecutionPlan( MergeOption?forMergeOption) { ObjectQueryExecutionPlan queryExecutionPlan1 = this._cachedPlan; if (queryExecutionPlan1 != null) { MergeOption?mergeOption = ObjectQueryState.GetMergeOption(forMergeOption, this.UserSpecifiedMergeOption); if (mergeOption.HasValue && mergeOption.Value != queryExecutionPlan1.MergeOption || (this._recompileRequired() || this.ObjectContext.ContextOptions.UseCSharpNullComparisonBehavior != this._useCSharpNullComparisonBehavior)) { queryExecutionPlan1 = (ObjectQueryExecutionPlan)null; } } if (queryExecutionPlan1 == null) { this._recompileRequired = (Func <bool>)null; this.ResetParameters(); ExpressionConverter expressionConverter = this.CreateExpressionConverter(); DbExpression dbExpression = expressionConverter.Convert(); this._recompileRequired = expressionConverter.RecompileRequired; MergeOption mergeOption = ObjectQueryState.EnsureMergeOption(forMergeOption, this.UserSpecifiedMergeOption, expressionConverter.PropagatedMergeOption); this._useCSharpNullComparisonBehavior = this.ObjectContext.ContextOptions.UseCSharpNullComparisonBehavior; this._linqParameters = expressionConverter.GetParameters(); if (this._linqParameters != null && this._linqParameters.Any <Tuple <ObjectParameter, QueryParameterExpression> >()) { ObjectParameterCollection parameterCollection = this.EnsureParameters(); parameterCollection.SetReadOnly(false); foreach (Tuple <ObjectParameter, QueryParameterExpression> linqParameter in this._linqParameters) { ObjectParameter objectParameter = linqParameter.Item1; parameterCollection.Add(objectParameter); } parameterCollection.SetReadOnly(true); } QueryCacheManager queryCacheManager = (QueryCacheManager)null; LinqQueryCacheKey key1 = (LinqQueryCacheKey)null; string key2; if (this.PlanCachingEnabled && !this._recompileRequired() && ExpressionKeyGen.TryGenerateKey(dbExpression, out key2)) { key1 = new LinqQueryCacheKey(key2, this.Parameters == null ? 0 : this.Parameters.Count, this.Parameters == null ? (string)null : this.Parameters.GetCacheKey(), expressionConverter.PropagatedSpan == null ? (string)null : expressionConverter.PropagatedSpan.GetCacheKey(), mergeOption, this.EffectiveStreamingBehavior, this._useCSharpNullComparisonBehavior, this.ElementType); queryCacheManager = this.ObjectContext.MetadataWorkspace.GetQueryCacheManager(); ObjectQueryExecutionPlan queryExecutionPlan2 = (ObjectQueryExecutionPlan)null; if (queryCacheManager.TryCacheLookup <LinqQueryCacheKey, ObjectQueryExecutionPlan>(key1, out queryExecutionPlan2)) { queryExecutionPlan1 = queryExecutionPlan2; } } if (queryExecutionPlan1 == null) { queryExecutionPlan1 = this._objectQueryExecutionPlanFactory.Prepare(this.ObjectContext, DbQueryCommandTree.FromValidExpression(this.ObjectContext.MetadataWorkspace, DataSpace.CSpace, dbExpression, !this._useCSharpNullComparisonBehavior), this.ElementType, mergeOption, this.EffectiveStreamingBehavior, expressionConverter.PropagatedSpan, (IEnumerable <Tuple <ObjectParameter, QueryParameterExpression> >)null, expressionConverter.AliasGenerator); if (key1 != null) { QueryCacheEntry inQueryCacheEntry = new QueryCacheEntry((QueryCacheKey)key1, (object)queryExecutionPlan1); QueryCacheEntry outQueryCacheEntry = (QueryCacheEntry)null; if (queryCacheManager.TryLookupAndAdd(inQueryCacheEntry, out outQueryCacheEntry)) { queryExecutionPlan1 = (ObjectQueryExecutionPlan)outQueryCacheEntry.GetTarget(); } } } this._cachedPlan = queryExecutionPlan1; } if (this._linqParameters != null) { foreach (Tuple <ObjectParameter, QueryParameterExpression> linqParameter in this._linqParameters) { ObjectParameter objectParameter = linqParameter.Item1; QueryParameterExpression parameterExpression = linqParameter.Item2; if (parameterExpression != null) { objectParameter.Value = parameterExpression.EvaluateParameter((object[])null); } } } return(queryExecutionPlan1); }
private static ObjectQueryState NewBuilderQuery(ObjectQueryState sourceQuery, Type elementType, StringBuilder queryText, bool allowsLimit, Span newSpan, IEnumerable<ObjectParameter> enumerableParams) { ObjectParameterCollection queryParams = enumerableParams as ObjectParameterCollection; if (queryParams == null && enumerableParams != null) { queryParams = new ObjectParameterCollection(sourceQuery.ObjectContext.Perspective); foreach (ObjectParameter objectParam in enumerableParams) { queryParams.Add(objectParam); } } EntitySqlQueryState newState = new EntitySqlQueryState(elementType, queryText.ToString(), allowsLimit, sourceQuery.ObjectContext, queryParams, newSpan); sourceQuery.ApplySettingsTo(newState); return newState; }
private ParameterReferenceRemover(ObjectParameterCollection availableParams) { DebugCheck.NotNull(availableParams); objectParameters = availableParams; }
internal static DbExpression RemoveParameterReferences(DbExpression expression, ObjectParameterCollection availableParameters) { var remover = new ParameterReferenceRemover(availableParameters); return remover.VisitExpression(expression); }
public EntityFramework5DatabaseHelper(ObjectQuery objectQuery) { Connection = (objectQuery.Context.Connection as EntityConnection)?.StoreConnection; parameters = objectQuery.Parameters; }
internal string ToTraceString(ObjectParameterCollection parameters = null) { var entityCommandDef = CommandDefinition as EntityCommandDefinition; if (entityCommandDef == null) { return(String.Empty); } var traceString = entityCommandDef.ToTraceString(); if (parameters == null || parameters.Count == 0) { return(traceString); } var command = CommandDefinition.CreateCommand(); var sb = new StringBuilder(); sb.Append(traceString); sb.Append("\n\n/*\n"); // append parameter information foreach (var objParam in parameters) { var index = command.Parameters.IndexOf(objParam.Name); if (index != -1) { var dbParam = command.Parameters[index]; sb.Append(dbParam.DbType); } else { Debug.Assert( false, "A parameter in the input ObjectParameterCollection does not have a match in the command definition's DbParameterCollection."); } sb.Append(" "); sb.Append(objParam.Name); sb.Append(" = "); var value = objParam.Value; var type = (value != null) ? value.GetType() : null; switch (Type.GetTypeCode(type)) { case TypeCode.Empty: case TypeCode.DBNull: sb.Append("(null)"); break; case TypeCode.Char: sb.Append("'"); sb.Append(value); sb.Append("'"); break; case TypeCode.String: sb.Append("\""); sb.Append(value); sb.Append("\""); break; default: sb.Append(value); break; } sb.Append("\n"); } sb.Append("*/\n"); return(sb.ToString()); }
internal ObjectResult <TResultType> Execute <TResultType>(ObjectContext context, ObjectParameterCollection parameterValues) { DbDataReader storeReader = null; try { // create entity command (just do this to snarf store command) EntityCommandDefinition commandDefinition = (EntityCommandDefinition)this.CommandDefinition; EntityCommand entityCommand = new EntityCommand((EntityConnection)context.Connection, commandDefinition); // pass through parameters and timeout values if (context.CommandTimeout.HasValue) { entityCommand.CommandTimeout = context.CommandTimeout.Value; } if (parameterValues != null) { foreach (ObjectParameter parameter in parameterValues) { int index = entityCommand.Parameters.IndexOf(parameter.Name); if (index != -1) { entityCommand.Parameters[index].Value = parameter.Value ?? DBNull.Value; } } } // acquire store reader storeReader = commandDefinition.ExecuteStoreCommands(entityCommand, CommandBehavior.Default); ShaperFactory <TResultType> shaperFactory = (ShaperFactory <TResultType>) this.ResultShaperFactory; Shaper <TResultType> shaper = shaperFactory.Create(storeReader, context, context.MetadataWorkspace, this.MergeOption, true); // create materializer delegate TypeUsage resultItemEdmType; if (ResultType.EdmType.BuiltInTypeKind == BuiltInTypeKind.CollectionType) { resultItemEdmType = ((CollectionType)ResultType.EdmType).TypeUsage; } else { resultItemEdmType = ResultType; } return(new ObjectResult <TResultType>(shaper, this._singleEntitySet, resultItemEdmType)); } catch (Exception) { if (null != storeReader) { // Note: The caller is responsible for disposing reader if creating // the enumerator fails. storeReader.Dispose(); } throw; } }
internal override ObjectQueryExecutionPlan GetExecutionPlan(MergeOption?forMergeOption) { Debug.Assert(this.Span == null, "Include span specified on compiled LINQ-based ObjectQuery instead of within the expression tree?"); // If this query has already been prepared, its current execution plan may no longer be valid. ObjectQueryExecutionPlan plan = this._cachedPlan; if (plan != null) { // Was a merge option specified in the call to Execute(MergeOption) or set via ObjectQuery.MergeOption? MergeOption?explicitMergeOption = GetMergeOption(forMergeOption, this.UserSpecifiedMergeOption); // If a merge option was explicitly specified, and it does not match the plan's merge option, then the plan is no longer valid. // If the context flag UseCSharpNullComparisonBehavior was modified, then the plan is no longer valid. if ((explicitMergeOption.HasValue && explicitMergeOption.Value != plan.MergeOption) || this._recompileRequired() || this.ObjectContext.ContextOptions.UseCSharpNullComparisonBehavior != this._useCSharpNullComparisonBehavior) { plan = null; } } // The plan may have been invalidated above, or this query may never have been prepared. if (plan == null) { // Metadata is required to generate the execution plan. this.ObjectContext.EnsureMetadata(); // Reset internal state this._recompileRequired = null; this.ResetParameters(); // Translate LINQ expression to a DbExpression ExpressionConverter converter = this.CreateExpressionConverter(); DbExpression queryExpression = converter.Convert(); // This delegate tells us when a part of the expression tree has changed requiring a recompile. this._recompileRequired = converter.RecompileRequired; // Determine the merge option, with the following precedence: // 1. A merge option was specified explicitly as the argument to Execute(MergeOption). // 2. The user has set the MergeOption property on the ObjectQuery instance. // 3. A merge option has been extracted from the 'root' query and propagated to the root of the expression tree. // 4. The global default merge option. MergeOption mergeOption = EnsureMergeOption(forMergeOption, this.UserSpecifiedMergeOption, converter.PropagatedMergeOption); this._useCSharpNullComparisonBehavior = this.ObjectContext.ContextOptions.UseCSharpNullComparisonBehavior; // If parameters were aggregated from referenced (non-LINQ) ObjectQuery instances then add them to the parameters collection _linqParameters = converter.GetParameters(); if (_linqParameters != null && _linqParameters.Count > 0) { ObjectParameterCollection currentParams = this.EnsureParameters(); currentParams.SetReadOnly(false); foreach (KeyValuePair <ObjectParameter, QueryParameterExpression> pair in _linqParameters) { // Note that it is safe to add the parameter directly only // because parameters are cloned before they are added to the // converter's parameter collection, or they came from this // instance's parameter collection in the first place. ObjectParameter convertedParam = pair.Key; currentParams.Add(convertedParam); } currentParams.SetReadOnly(true); } // Try retrieving the execution plan from the global query cache (if plan caching is enabled). System.Data.Common.QueryCache.QueryCacheManager cacheManager = null; System.Data.Common.QueryCache.LinqQueryCacheKey cacheKey = null; if (this.PlanCachingEnabled && !this._recompileRequired()) { // Create a new cache key that reflects the current state of the Parameters collection // and the Span object (if any), and uses the specified merge option. string expressionKey; if (ExpressionKeyGen.TryGenerateKey(queryExpression, out expressionKey)) { cacheKey = new System.Data.Common.QueryCache.LinqQueryCacheKey( expressionKey, (null == this.Parameters ? 0 : this.Parameters.Count), (null == this.Parameters ? null : this.Parameters.GetCacheKey()), (null == converter.PropagatedSpan ? null : converter.PropagatedSpan.GetCacheKey()), mergeOption, this._useCSharpNullComparisonBehavior, this.ElementType); cacheManager = this.ObjectContext.MetadataWorkspace.GetQueryCacheManager(); ObjectQueryExecutionPlan executionPlan = null; if (cacheManager.TryCacheLookup(cacheKey, out executionPlan)) { plan = executionPlan; } } } // If execution plan wasn't retrieved from the cache, build a new one and cache it. if (plan == null) { DbQueryCommandTree tree = DbQueryCommandTree.FromValidExpression(this.ObjectContext.MetadataWorkspace, DataSpace.CSpace, queryExpression); plan = ObjectQueryExecutionPlan.Prepare(this.ObjectContext, tree, this.ElementType, mergeOption, converter.PropagatedSpan, null, converter.AliasGenerator); // If caching is enabled then update the cache now. // Note: the logic is the same as in EntitySqlQueryState. if (cacheKey != null) { var newEntry = new QueryCacheEntry(cacheKey, plan); QueryCacheEntry foundEntry = null; if (cacheManager.TryLookupAndAdd(newEntry, out foundEntry)) { // If TryLookupAndAdd returns 'true' then the entry was already present in the cache when the attempt to add was made. // In this case the existing execution plan should be used. plan = (ObjectQueryExecutionPlan)foundEntry.GetTarget(); } } } // Remember the current plan in the local cache, so that we don't have to recalc the key and look into the global cache // if the same instance of query gets executed more than once. this._cachedPlan = plan; } // Evaluate parameter values for the query. if (_linqParameters != null) { foreach (KeyValuePair <ObjectParameter, QueryParameterExpression> pair in _linqParameters) { ObjectParameter parameter = pair.Key; QueryParameterExpression parameterExpression = pair.Value; if (null != parameterExpression) { parameter.Value = parameterExpression.EvaluateParameter(null); } } } return(plan); }
internal virtual async Task <ObjectResult <TResultType> > ExecuteAsync <TResultType>( ObjectContext context, ObjectParameterCollection parameterValues, CancellationToken cancellationToken) { DbDataReader storeReader = null; try { // create entity command (just do this to snarf store command) var commandDefinition = (EntityCommandDefinition)CommandDefinition; var entityCommand = new EntityCommand((EntityConnection)context.Connection, commandDefinition); // pass through parameters and timeout values if (context.CommandTimeout.HasValue) { entityCommand.CommandTimeout = context.CommandTimeout.Value; } if (parameterValues != null) { foreach (var parameter in parameterValues) { var index = entityCommand.Parameters.IndexOf(parameter.Name); if (index != -1) { entityCommand.Parameters[index].Value = parameter.Value ?? DBNull.Value; } } } // acquire store reader storeReader = await commandDefinition.ExecuteStoreCommandsAsync(entityCommand, CommandBehavior.Default, cancellationToken). ConfigureAwait(continueOnCapturedContext: false); var shaperFactory = (ShaperFactory <TResultType>)ResultShaperFactory; var shaper = shaperFactory.Create(storeReader, context, context.MetadataWorkspace, MergeOption, true); // create materializer delegate TypeUsage resultItemEdmType; if (ResultType.EdmType.BuiltInTypeKind == BuiltInTypeKind.CollectionType) { resultItemEdmType = ((CollectionType)ResultType.EdmType).TypeUsage; } else { resultItemEdmType = ResultType; } return(new ObjectResult <TResultType>(shaper, _singleEntitySet, resultItemEdmType)); } catch (Exception) { if (null != storeReader) { // Note: The caller is responsible for disposing reader if creating // the enumerator fails. storeReader.Dispose(); } throw; } }
internal override ObjectQueryExecutionPlan GetExecutionPlan( MergeOption?forMergeOption) { ObjectQueryExecutionPlan queryExecutionPlan = (ObjectQueryExecutionPlan)null; CompiledQueryCacheEntry compiledQueryCacheEntry = this._cacheEntry; bool comparisonBehavior = this.ObjectContext.ContextOptions.UseCSharpNullComparisonBehavior; if (compiledQueryCacheEntry != null) { MergeOption mergeOption = ObjectQueryState.EnsureMergeOption(forMergeOption, this.UserSpecifiedMergeOption, compiledQueryCacheEntry.PropagatedMergeOption); queryExecutionPlan = compiledQueryCacheEntry.GetExecutionPlan(mergeOption, comparisonBehavior); if (queryExecutionPlan == null) { ExpressionConverter expressionConverter = this.CreateExpressionConverter(); DbExpression query = expressionConverter.Convert(); IEnumerable <Tuple <ObjectParameter, QueryParameterExpression> > parameters = expressionConverter.GetParameters(); ObjectQueryExecutionPlan newPlan = this._objectQueryExecutionPlanFactory.Prepare(this.ObjectContext, DbQueryCommandTree.FromValidExpression(this.ObjectContext.MetadataWorkspace, DataSpace.CSpace, query, !comparisonBehavior), this.ElementType, mergeOption, this.EffectiveStreamingBehavior, expressionConverter.PropagatedSpan, parameters, expressionConverter.AliasGenerator); queryExecutionPlan = compiledQueryCacheEntry.SetExecutionPlan(newPlan, comparisonBehavior); } } else { QueryCacheManager queryCacheManager = this.ObjectContext.MetadataWorkspace.GetQueryCacheManager(); CompiledQueryCacheKey key = new CompiledQueryCacheKey(this._cacheToken); if (queryCacheManager.TryCacheLookup <CompiledQueryCacheKey, CompiledQueryCacheEntry>(key, out compiledQueryCacheEntry)) { this._cacheEntry = compiledQueryCacheEntry; MergeOption mergeOption = ObjectQueryState.EnsureMergeOption(forMergeOption, this.UserSpecifiedMergeOption, compiledQueryCacheEntry.PropagatedMergeOption); queryExecutionPlan = compiledQueryCacheEntry.GetExecutionPlan(mergeOption, comparisonBehavior); } if (queryExecutionPlan == null) { ExpressionConverter expressionConverter = this.CreateExpressionConverter(); DbExpression query = expressionConverter.Convert(); IEnumerable <Tuple <ObjectParameter, QueryParameterExpression> > parameters = expressionConverter.GetParameters(); DbQueryCommandTree tree = DbQueryCommandTree.FromValidExpression(this.ObjectContext.MetadataWorkspace, DataSpace.CSpace, query, !comparisonBehavior); if (compiledQueryCacheEntry == null) { compiledQueryCacheEntry = new CompiledQueryCacheEntry((QueryCacheKey)key, expressionConverter.PropagatedMergeOption); QueryCacheEntry outQueryCacheEntry; if (queryCacheManager.TryLookupAndAdd((QueryCacheEntry)compiledQueryCacheEntry, out outQueryCacheEntry)) { compiledQueryCacheEntry = (CompiledQueryCacheEntry)outQueryCacheEntry; } this._cacheEntry = compiledQueryCacheEntry; } MergeOption mergeOption = ObjectQueryState.EnsureMergeOption(forMergeOption, this.UserSpecifiedMergeOption, compiledQueryCacheEntry.PropagatedMergeOption); queryExecutionPlan = compiledQueryCacheEntry.GetExecutionPlan(mergeOption, comparisonBehavior); if (queryExecutionPlan == null) { ObjectQueryExecutionPlan newPlan = this._objectQueryExecutionPlanFactory.Prepare(this.ObjectContext, tree, this.ElementType, mergeOption, this.EffectiveStreamingBehavior, expressionConverter.PropagatedSpan, parameters, expressionConverter.AliasGenerator); queryExecutionPlan = compiledQueryCacheEntry.SetExecutionPlan(newPlan, comparisonBehavior); } } } ObjectParameterCollection parameterCollection = this.EnsureParameters(); if (queryExecutionPlan.CompiledQueryParameters != null && queryExecutionPlan.CompiledQueryParameters.Any <Tuple <ObjectParameter, QueryParameterExpression> >()) { parameterCollection.SetReadOnly(false); parameterCollection.Clear(); foreach (Tuple <ObjectParameter, QueryParameterExpression> compiledQueryParameter in queryExecutionPlan.CompiledQueryParameters) { ObjectParameter objectParameter = compiledQueryParameter.Item1.ShallowCopy(); QueryParameterExpression parameterExpression = compiledQueryParameter.Item2; parameterCollection.Add(objectParameter); if (parameterExpression != null) { objectParameter.Value = parameterExpression.EvaluateParameter(this._parameterValues); } } } parameterCollection.SetReadOnly(true); return(queryExecutionPlan); }