Skip to content

Commit

Permalink
Merge branch 'hotfix-1.0.1' into dev
Browse files Browse the repository at this point in the history
  • Loading branch information
maumar committed Jul 8, 2016
2 parents 53cea6f + 05b24c3 commit 0669372
Show file tree
Hide file tree
Showing 18 changed files with 942 additions and 117 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -792,5 +792,87 @@ public IAsyncEnumerable<EntityLoadInfo> Load(QueryContext queryContext, IInclude

public void Dispose() => _includeCollectionIterator?.Dispose();
}

/// <summary>
/// This API supports the Entity Framework Core infrastructure and is not intended to be used
/// directly from your code. This API may change or be removed in future releases.
/// </summary>
public virtual MethodInfo InjectParametersMethod => _injectParametersMethodInfo;

private static readonly MethodInfo _injectParametersMethodInfo
= typeof(AsyncQueryMethodProvider)
.GetTypeInfo().GetDeclaredMethod(nameof(_InjectParameters));

[UsedImplicitly]
// ReSharper disable once InconsistentNaming
private static IAsyncEnumerable<TElement> _InjectParameters<TElement>(
QueryContext queryContext,
IAsyncEnumerable<TElement> source,
string[] parameterNames,
object[] parameterValues)
=> new ParameterInjector<TElement>(queryContext, source, parameterNames, parameterValues);

private sealed class ParameterInjector<TElement> : IAsyncEnumerable<TElement>
{
private readonly QueryContext _queryContext;
private readonly IAsyncEnumerable<TElement> _innerEnumerable;
private readonly string[] _parameterNames;
private readonly object[] _parameterValues;

public ParameterInjector(
QueryContext queryContext,
IAsyncEnumerable<TElement> innerEnumerable,
string[] parameterNames,
object[] parameterValues)
{
_queryContext = queryContext;
_innerEnumerable = innerEnumerable;
_parameterNames = parameterNames;
_parameterValues = parameterValues;
}

IAsyncEnumerator<TElement> IAsyncEnumerable<TElement>.GetEnumerator() => new InjectParametersEnumerator(this);

private sealed class InjectParametersEnumerator : IAsyncEnumerator<TElement>
{
private readonly ParameterInjector<TElement> _parameterInjector;
private readonly IAsyncEnumerator<TElement> _innerEnumerator;
private bool _disposed;

public InjectParametersEnumerator(ParameterInjector<TElement> parameterInjector)
{
_parameterInjector = parameterInjector;

for (var i = 0; i < _parameterInjector._parameterNames.Length; i++)
{
_parameterInjector._queryContext.AddParameter(
_parameterInjector._parameterNames[i],
_parameterInjector._parameterValues[i]);
}

_innerEnumerator = _parameterInjector._innerEnumerable.GetEnumerator();
}

public TElement Current => _innerEnumerator.Current;

public async Task<bool> MoveNext(CancellationToken cancellationToken)
=> await _innerEnumerator.MoveNext(cancellationToken);

public void Dispose()
{
if (!_disposed)
{
_innerEnumerator.Dispose();

foreach (var parameterName in _parameterInjector._parameterNames)
{
_parameterInjector._queryContext.RemoveParameter(parameterName);
}

_disposed = true;
}
}
}
}
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@
using System.Reflection;
using JetBrains.Annotations;
using Microsoft.EntityFrameworkCore.Extensions.Internal;
using Microsoft.EntityFrameworkCore.Storage;
using Microsoft.EntityFrameworkCore.Utilities;
using Remotion.Linq.Clauses;

Expand Down Expand Up @@ -57,6 +58,24 @@ protected override Expression VisitMethodCall(MethodCallExpression node)
queryArguments));
}

if (node.Method.MethodIsClosedFormOf(
_relationalQueryCompilationContext.QueryMethodProvider.InjectParametersMethod))
{
var sourceArgument = (MethodCallExpression)Visit(node.Arguments[1]);
if (sourceArgument.Method.MethodIsClosedFormOf(
_relationalQueryCompilationContext.QueryMethodProvider.GetResultMethod))
{
var getResultArgument = sourceArgument.Arguments[0];
var newGetResultArgument = Expression.Call(
_relationalQueryCompilationContext.QueryMethodProvider.InjectParametersMethod.MakeGenericMethod(typeof(ValueBuffer)),
node.Arguments[0], getResultArgument, node.Arguments[2], node.Arguments[3]);

return Expression.Call(sourceArgument.Method, newGetResultArgument);
}

return sourceArgument;
}

// ReSharper disable once LoopCanBePartlyConvertedToQuery
foreach (var expression in node.Arguments)
{
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -617,7 +617,9 @@ var expression
.BindMethodCallExpression(methodCallExpression, CreateAliasedColumnExpressionCore);
}

return expression;
return expression == null
? _queryModelVisitor.BindMethodToOuterQueryParameter(methodCallExpression)
: expression;
}

/// <summary>
Expand Down Expand Up @@ -685,7 +687,9 @@ var selectExpression
}
}

return aliasExpression;
return aliasExpression == null
? _queryModelVisitor.BindMemberToOuterQueryParameter(expression)
: aliasExpression;
}

private AliasExpression CreateAliasedColumnExpression(
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -94,6 +94,14 @@ public interface IQueryMethodProvider
/// </value>
MethodInfo CreateCollectionRelatedEntitiesLoaderMethod { get; }

/// <summary>
/// Gets the inject parameters method.
/// </summary>
/// <value>
/// The pre execute method.
/// </value>
MethodInfo InjectParametersMethod { get; }

/// <summary>
/// Gets the type of the group join include.
/// </summary>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -387,6 +387,19 @@ protected override Expression VisitMethodCall(MethodCallExpression methodCallExp
methodCallExpression.Arguments);
}

if (methodCallExpression.Method.MethodIsClosedFormOf(
_relationalQueryCompilationContext.QueryMethodProvider.InjectParametersMethod))
{
var newSource = VisitMethodCall((MethodCallExpression)methodCallExpression.Arguments[1]);

return Expression.Call(
methodCallExpression.Method,
methodCallExpression.Arguments[0],
newSource,
methodCallExpression.Arguments[2],
methodCallExpression.Arguments[3]);
}

return base.VisitMethodCall(methodCallExpression);
}
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -62,6 +62,9 @@ public override bool Equals(object obj)
}

public override int GetHashCode() => 0;

public CommandCacheKey Clone() => new CommandCacheKey(
new Dictionary<string, object>((Dictionary<string, object>)_parameterValues));
}

private readonly IRelationalValueBufferFactoryFactory _valueBufferFactoryFactory;
Expand Down Expand Up @@ -112,7 +115,7 @@ public virtual IRelationalCommand GetRelationalCommand(

if (generator.IsCacheable)
{
_commandCache.TryAdd(key, relationalCommand);
_commandCache.TryAdd(key.Clone(), relationalCommand);
}

return relationalCommand;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@
// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.

using System;
using System.Collections;
using System.Collections.Generic;
using System.Linq;
using System.Reflection;
Expand Down Expand Up @@ -529,5 +530,92 @@ public IEnumerable<EntityLoadInfo> Load(QueryContext queryContext, IIncludeKeyCo

public void Dispose() => _includeCollectionIterator?.Dispose();
}

/// <summary>
/// This API supports the Entity Framework Core infrastructure and is not intended to be used
/// directly from your code. This API may change or be removed in future releases.
/// </summary>
public virtual MethodInfo InjectParametersMethod => _injectParametersMethodInfo;

private static readonly MethodInfo _injectParametersMethodInfo
= typeof(QueryMethodProvider)
.GetTypeInfo().GetDeclaredMethod(nameof(_InjectParameters));

[UsedImplicitly]
// ReSharper disable once InconsistentNaming
private static IEnumerable<TElement> _InjectParameters<TElement>(
QueryContext queryContext,
IEnumerable<TElement> source,
string[] parameterNames,
object[] parameterValues)
=> new ParameterInjector<TElement>(queryContext, source, parameterNames, parameterValues);

private sealed class ParameterInjector<TElement> : IEnumerable<TElement>
{
private readonly QueryContext _queryContext;
private readonly IEnumerable<TElement> _innerEnumerable;
private readonly string[] _parameterNames;
private readonly object[] _parameterValues;

public ParameterInjector(
QueryContext queryContext,
IEnumerable<TElement> innerEnumerable,
string[] parameterNames,
object[] parameterValues)
{
_queryContext = queryContext;
_innerEnumerable = innerEnumerable;
_parameterNames = parameterNames;
_parameterValues = parameterValues;
}

public IEnumerator<TElement> GetEnumerator() => new InjectParametersEnumerator(this);

IEnumerator IEnumerable.GetEnumerator() => GetEnumerator();

private sealed class InjectParametersEnumerator : IEnumerator<TElement>
{
private readonly ParameterInjector<TElement> _parameterInjector;
private readonly IEnumerator<TElement> _innerEnumerator;
private bool _disposed;

public InjectParametersEnumerator(ParameterInjector<TElement> parameterInjector)
{
_parameterInjector = parameterInjector;

for (var i = 0; i < _parameterInjector._parameterNames.Length; i++)
{
_parameterInjector._queryContext.AddParameter(
_parameterInjector._parameterNames[i],
_parameterInjector._parameterValues[i]);
}

_innerEnumerator = _parameterInjector._innerEnumerable.GetEnumerator();
}

public TElement Current => _innerEnumerator.Current;

object IEnumerator.Current => _innerEnumerator.Current;

public bool MoveNext() => _innerEnumerator.MoveNext();

public void Reset() => _innerEnumerator.Reset();

public void Dispose()
{
if (!_disposed)
{
_innerEnumerator.Dispose();

foreach (var parameterName in _parameterInjector._parameterNames)
{
_parameterInjector._queryContext.RemoveParameter(parameterName);
}

_disposed = true;
}
}
}
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -52,6 +52,7 @@ public RelationalQueryCompilationContext(
Check.NotNull(queryMethodProvider, nameof(queryMethodProvider));

QueryMethodProvider = queryMethodProvider;
ParentQueryReferenceParameters = new List<string>();
}

/// <summary>
Expand All @@ -62,6 +63,14 @@ public RelationalQueryCompilationContext(
/// </value>
public virtual IQueryMethodProvider QueryMethodProvider { get; }

/// <summary>
/// Gets the list of parameter names that represent reference to a parent query.
/// </summary>
/// <value>
/// The list of parameter names that represent reference to a parent query.
/// </value>
public virtual IList<string> ParentQueryReferenceParameters { get; }

/// <summary>
/// Creates a query model visitor.
/// </summary>
Expand Down
Loading

0 comments on commit 0669372

Please sign in to comment.