Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -745,5 +745,5 @@ private static Expression MatchTypes(Expression expression, Type targetType)

[UsedImplicitly]
private static T GetParameterValue<T>(QueryContext queryContext, string parameterName)
=> (T)queryContext.ParameterValues[parameterName]!;
=> (T)queryContext.Parameters[parameterName]!;
}
Original file line number Diff line number Diff line change
Expand Up @@ -67,7 +67,7 @@ public PagingQueryingEnumerable(
_cosmosContainer = rootEntityType.GetContainer()
?? throw new UnreachableException("Root entity type without a Cosmos container.");
_cosmosPartitionKey = GeneratePartitionKey(
rootEntityType, partitionKeyPropertyValues, _cosmosQueryContext.ParameterValues);
rootEntityType, partitionKeyPropertyValues, _cosmosQueryContext.Parameters);
}

public IAsyncEnumerator<CosmosPage<T>> GetAsyncEnumerator(CancellationToken cancellationToken = default)
Expand All @@ -77,9 +77,9 @@ private CosmosSqlQuery GenerateQuery()
=> _querySqlGeneratorFactory.Create().GetSqlQuery(
(SelectExpression)new ParameterInliner(
_sqlExpressionFactory,
_cosmosQueryContext.ParameterValues)
_cosmosQueryContext.Parameters)
.Visit(_selectExpression),
_cosmosQueryContext.ParameterValues);
_cosmosQueryContext.Parameters);

private sealed class AsyncEnumerator : IAsyncEnumerator<CosmosPage<T>>
{
Expand Down Expand Up @@ -135,11 +135,11 @@ public async ValueTask<bool> MoveNextAsync()

_hasExecuted = true;

var maxItemCount = (int)_cosmosQueryContext.ParameterValues[_queryingEnumerable._maxItemCountParameterName];
var maxItemCount = (int)_cosmosQueryContext.Parameters[_queryingEnumerable._maxItemCountParameterName];
var continuationToken =
(string)_cosmosQueryContext.ParameterValues[_queryingEnumerable._continuationTokenParameterName];
(string)_cosmosQueryContext.Parameters[_queryingEnumerable._continuationTokenParameterName];
var responseContinuationTokenLimitInKb = (int?)
_cosmosQueryContext.ParameterValues[_queryingEnumerable._responseContinuationTokenLimitInKbParameterName];
_cosmosQueryContext.Parameters[_queryingEnumerable._responseContinuationTokenLimitInKbParameterName];

var sqlQuery = _queryingEnumerable.GenerateQuery();

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -57,7 +57,7 @@ public QueryingEnumerable(
_cosmosContainer = rootEntityType.GetContainer()
?? throw new UnreachableException("Root entity type without a Cosmos container.");
_cosmosPartitionKey = GeneratePartitionKey(
rootEntityType, partitionKeyPropertyValues, _cosmosQueryContext.ParameterValues);
rootEntityType, partitionKeyPropertyValues, _cosmosQueryContext.Parameters);
}

public IAsyncEnumerator<T> GetAsyncEnumerator(CancellationToken cancellationToken = default)
Expand All @@ -73,9 +73,9 @@ private CosmosSqlQuery GenerateQuery()
=> _querySqlGeneratorFactory.Create().GetSqlQuery(
(SelectExpression)new ParameterInliner(
_sqlExpressionFactory,
_cosmosQueryContext.ParameterValues)
_cosmosQueryContext.Parameters)
.Visit(_selectExpression),
_cosmosQueryContext.ParameterValues);
_cosmosQueryContext.Parameters);

public string ToQueryString()
{
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -53,7 +53,7 @@ public ReadItemQueryingEnumerable(
_cosmosContainer = rootEntityType.GetContainer()
?? throw new UnreachableException("Root entity type without a Cosmos container.");
_cosmosPartitionKey = GeneratePartitionKey(
rootEntityType, partitionKeyPropertyValues, _cosmosQueryContext.ParameterValues);
rootEntityType, partitionKeyPropertyValues, _cosmosQueryContext.Parameters);
}

public IAsyncEnumerator<T> GetAsyncEnumerator(CancellationToken cancellationToken = default)
Expand Down Expand Up @@ -83,7 +83,7 @@ private bool TryGetResourceId(out string resourceId)
{
var value = _readItemInfo.PropertyValues[property] switch
{
SqlParameterExpression { Name: var parameterName } => _cosmosQueryContext.ParameterValues[parameterName],
SqlParameterExpression { Name: var parameterName } => _cosmosQueryContext.Parameters[parameterName],
SqlConstantExpression { Value: var constantValue } => constantValue,
_ => throw new UnreachableException()
};
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -1179,7 +1179,7 @@ when memberInitExpression.Bindings.SingleOrDefault(

private static T? ParameterValueExtractor<T>(QueryContext context, string baseParameterName, IProperty property)
{
var baseParameter = context.ParameterValues[baseParameterName];
var baseParameter = context.Parameters[baseParameterName];
return baseParameter == null ? (T?)(object?)null : (T?)property.GetGetter().GetClrValue(baseParameter);
}

Expand All @@ -1188,7 +1188,7 @@ when memberInitExpression.Bindings.SingleOrDefault(
string baseParameterName,
IProperty property)
{
if (context.ParameterValues[baseParameterName] is not IEnumerable<TEntity> baseListParameter)
if (context.Parameters[baseParameterName] is not IEnumerable<TEntity> baseListParameter)
{
return null;
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -797,7 +797,7 @@ or nameof(EntityFrameworkQueryableExtensions.ExecuteUpdateAsync),
{
// Special case: this is a non-lambda argument (Skip/Take/FromSql).
// Simply add the argument directly as a parameter
code.AppendLine($"""queryContext.AddParameter("{evaluatableRootPaths.ParameterName}", {parameterName});""");
code.AppendLine($"""queryContext.Parameters.Add("{evaluatableRootPaths.ParameterName}", {parameterName});""");
continue;
}

Expand Down Expand Up @@ -849,7 +849,7 @@ void GenerateCapturedVariableExtractors(
// (see ExpressionTreeFuncletizer.Evaluate()).
// TODO: Basically this means that the evaluator should come from ExpressionTreeFuncletizer itself, as part of its outputs
// TODO: Integrate try/catch around the evaluation?
code.AppendLine("queryContext.AddParameter(");
code.AppendLine("queryContext.Parameters.Add(");
using (code.Indent())
{
code
Expand Down Expand Up @@ -893,7 +893,7 @@ void GenerateCapturedVariableExtractors(
};

code.AppendLine(
$"""queryContext.AddParameter("{evaluatableRootPaths.ParameterName}", {argumentsParameter});""");
$"""queryContext.Parameters.Add("{evaluatableRootPaths.ParameterName}", {argumentsParameter});""");

break;
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -1216,7 +1216,7 @@ private static Expression ProcessSingleResultScalar(

[UsedImplicitly]
private static T GetParameterValue<T>(QueryContext queryContext, string parameterName)
=> (T)queryContext.ParameterValues[parameterName]!;
=> (T)queryContext.Parameters[parameterName]!;

private static bool IsConvertedToNullable(Expression result, Expression original)
=> result.Type.IsNullableType()
Expand Down Expand Up @@ -1480,7 +1480,7 @@ when CanEvaluate(memberInitExpression):

private static T? ParameterValueExtractor<T>(QueryContext context, string baseParameterName, IProperty property)
{
var baseParameter = context.ParameterValues[baseParameterName];
var baseParameter = context.Parameters[baseParameterName];
return baseParameter == null ? (T?)(object?)null : (T?)property.GetGetter().GetClrValue(baseParameter);
}

Expand All @@ -1489,7 +1489,7 @@ when CanEvaluate(memberInitExpression):
string baseParameterName,
IProperty property)
{
if (!(context.ParameterValues[baseParameterName] is IEnumerable<TEntity> baseListParameter))
if (!(context.Parameters[baseParameterName] is IEnumerable<TEntity> baseListParameter))
{
return null;
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,7 @@ public static IRelationalCommand RentAndPopulateRelationalCommand(
this RelationalCommandResolver relationalCommandResolver,
RelationalQueryContext queryContext)
{
var relationalCommandTemplate = relationalCommandResolver(queryContext.ParameterValues);
var relationalCommandTemplate = relationalCommandResolver(queryContext.Parameters);
var relationalCommand = queryContext.Connection.RentCommand();
relationalCommand.PopulateFrom(relationalCommandTemplate);
return relationalCommand;
Expand Down
45 changes: 45 additions & 0 deletions src/EFCore.Relational/Query/CacheSafeParameterFacade.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,45 @@
// Licensed to the .NET Foundation under one or more agreements.
// The .NET Foundation licenses this file to you under the MIT license.

using System;

namespace Microsoft.EntityFrameworkCore.Query;

/// <summary>
/// A facade over <see cref="QueryContext.Parameters" /> which provides cache-safe way to access parameters after the SQL cache.
/// </summary>
/// <remarks>
/// The SQL cache only includes then nullability of parameters in its cache key. Accordingly, this type exposes an API for checking
/// the nullability of a parameter. It also allows retrieving the full parameter dictionary for arbitrary checks, but when this
/// API is called, the facade records this fact, and the resulting SQL will not get cached.
/// </remarks>
public sealed class CacheSafeParameterFacade(Dictionary<string, object?> parameters)
{
/// <summary>
/// Returns whether the parameter with the given name is null.
/// </summary>
/// <remarks>
/// The method assumes that the parameter with the given name exists in the dictionary,
/// and otherwise throws <see cref="UnreachableException" />.
/// </remarks>
public bool IsParameterNull(string parameterName)
=> parameters.TryGetValue(parameterName, out var value)
? value is null
: throw new UnreachableException($"Parameter with name '{parameterName}' does not exist.");

/// <summary>
/// Returns the full dictionary of parameters, and disables caching for the generated SQL.
/// </summary>
public Dictionary<string, object?> GetParametersAndDisableSqlCaching()
{
CanCache = false;

return parameters;
}

/// <summary>
/// Whether the SQL generated using this facade can be cached, i.e. whether the full dictionary of parameters
/// has been accessed.
/// </summary>
public bool CanCache { get; private set; } = true;
}
Original file line number Diff line number Diff line change
Expand Up @@ -128,11 +128,11 @@ IEnumerator IEnumerable.GetEnumerator()
/// doing so can result in application failures when updating to a new Entity Framework Core release.
/// </summary>
public virtual DbCommand CreateDbCommand()
=> _relationalCommandResolver(_relationalQueryContext.ParameterValues)
=> _relationalCommandResolver(_relationalQueryContext.Parameters)
.CreateDbCommand(
new RelationalCommandParameterObject(
_relationalQueryContext.Connection,
_relationalQueryContext.ParameterValues,
_relationalQueryContext.Parameters,
null,
null,
null,
Expand Down Expand Up @@ -269,7 +269,7 @@ private static bool InitializeReader(Enumerator enumerator)
enumerator._dataReader = relationalCommand.ExecuteReader(
new RelationalCommandParameterObject(
enumerator._relationalQueryContext.Connection,
enumerator._relationalQueryContext.ParameterValues,
enumerator._relationalQueryContext.Parameters,
enumerator._readerColumns,
enumerator._relationalQueryContext.Context,
enumerator._relationalQueryContext.CommandLogger,
Expand Down Expand Up @@ -384,7 +384,7 @@ private static async Task<bool> InitializeReaderAsync(AsyncEnumerator enumerator
enumerator._dataReader = await relationalCommand.ExecuteReaderAsync(
new RelationalCommandParameterObject(
enumerator._relationalQueryContext.Connection,
enumerator._relationalQueryContext.ParameterValues,
enumerator._relationalQueryContext.Parameters,
enumerator._readerColumns,
enumerator._relationalQueryContext.Context,
enumerator._relationalQueryContext.CommandLogger,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -139,11 +139,11 @@ IEnumerator IEnumerable.GetEnumerator()
/// doing so can result in application failures when updating to a new Entity Framework Core release.
/// </summary>
public virtual DbCommand CreateDbCommand()
=> _relationalCommandResolver(_relationalQueryContext.ParameterValues)
=> _relationalCommandResolver(_relationalQueryContext.Parameters)
.CreateDbCommand(
new RelationalCommandParameterObject(
_relationalQueryContext.Connection,
_relationalQueryContext.ParameterValues,
_relationalQueryContext.Parameters,
null,
null,
null, CommandSource.LinqQuery),
Expand Down Expand Up @@ -339,7 +339,7 @@ private static bool InitializeReader(Enumerator enumerator)
var dataReader = enumerator._dataReader = relationalCommand.ExecuteReader(
new RelationalCommandParameterObject(
enumerator._relationalQueryContext.Connection,
enumerator._relationalQueryContext.ParameterValues,
enumerator._relationalQueryContext.Parameters,
enumerator._readerColumns,
enumerator._relationalQueryContext.Context,
enumerator._relationalQueryContext.CommandLogger,
Expand Down Expand Up @@ -519,7 +519,7 @@ private static async Task<bool> InitializeReaderAsync(AsyncEnumerator enumerator
var dataReader = enumerator._dataReader = await relationalCommand.ExecuteReaderAsync(
new RelationalCommandParameterObject(
enumerator._relationalQueryContext.Connection,
enumerator._relationalQueryContext.ParameterValues,
enumerator._relationalQueryContext.Parameters,
enumerator._readerColumns,
enumerator._relationalQueryContext.Context,
enumerator._relationalQueryContext.CommandLogger,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -149,11 +149,11 @@ IEnumerator IEnumerable.GetEnumerator()
/// doing so can result in application failures when updating to a new Entity Framework Core release.
/// </summary>
public virtual DbCommand CreateDbCommand()
=> _relationalCommandResolver(_relationalQueryContext.ParameterValues)
=> _relationalCommandResolver(_relationalQueryContext.Parameters)
.CreateDbCommand(
new RelationalCommandParameterObject(
_relationalQueryContext.Connection,
_relationalQueryContext.ParameterValues,
_relationalQueryContext.Parameters,
null,
null,
null, CommandSource.LinqQuery),
Expand Down Expand Up @@ -339,7 +339,7 @@ private static bool InitializeReader(Enumerator enumerator)
var dataReader = enumerator._dataReader = relationalCommand.ExecuteReader(
new RelationalCommandParameterObject(
enumerator._relationalQueryContext.Connection,
enumerator._relationalQueryContext.ParameterValues,
enumerator._relationalQueryContext.Parameters,
enumerator._readerColumns,
enumerator._relationalQueryContext.Context,
enumerator._relationalQueryContext.CommandLogger,
Expand Down Expand Up @@ -510,7 +510,7 @@ private static async Task<bool> InitializeReaderAsync(AsyncEnumerator enumerator
var dataReader = enumerator._dataReader = await relationalCommand.ExecuteReaderAsync(
new RelationalCommandParameterObject(
enumerator._relationalQueryContext.Connection,
enumerator._relationalQueryContext.ParameterValues,
enumerator._relationalQueryContext.Parameters,
enumerator._readerColumns,
enumerator._relationalQueryContext.Context,
enumerator._relationalQueryContext.CommandLogger,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -70,7 +70,7 @@ public virtual IRelationalCommandTemplate GetRelationalCommandTemplate(Dictionar
{
if (!_memoryCache.TryGetValue(cacheKey, out relationalCommandTemplate))
{
var queryExpression = _relationalParameterBasedSqlProcessor.Optimize(
var queryExpression = _relationalParameterBasedSqlProcessor.Process(
_queryExpression, parameters, out var canCache);
relationalCommandTemplate = _querySqlGeneratorFactory.Create().GetCommand(queryExpression);

Expand Down
Loading