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
13 changes: 9 additions & 4 deletions src/EntityFramework7.Core/Query/CompiledQueryCache.cs
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@
using Remotion.Linq.Clauses.Expressions;
using Remotion.Linq.Clauses.StreamedData;
using Remotion.Linq.Parsing.ExpressionVisitors.Transformation;
using Remotion.Linq.Parsing.ExpressionVisitors.TreeEvaluation;
using Remotion.Linq.Parsing.Structure;
using Remotion.Linq.Parsing.Structure.ExpressionTreeProcessors;
using Remotion.Linq.Parsing.Structure.NodeTypeProviders;
Expand Down Expand Up @@ -160,7 +161,7 @@ private CompiledQuery GetOrAdd(

var parameterizedQuery
= ParameterExtractingExpressionVisitor
.ExtractParameters(query, queryContext);
.ExtractParameters(query, queryContext, new NullEvaluatableExpressionFilter());

var cacheKey
= database.Model.GetHashCode().ToString()
Expand Down Expand Up @@ -204,11 +205,15 @@ private static QueryParser CreateQueryParser()
_cachedNodeTypeProvider.Value,
new CompoundExpressionTreeProcessor(new IExpressionTreeProcessor[]
{
new PartialEvaluatingExpressionTreeProcessor(),
new PartialEvaluatingExpressionTreeProcessor(new NullEvaluatableExpressionFilter()),
new FunctionEvaluationEnablingProcessor(),
new TransformingExpressionTreeProcessor(ExpressionTransformerRegistry.CreateDefault())
})));

private class NullEvaluatableExpressionFilter : EvaluatableExpressionFilterBase
{
}

private class FunctionEvaluationEnablingProcessor : IExpressionTreeProcessor
{
public Expression Process(Expression expressionTree)
Expand Down Expand Up @@ -247,7 +252,7 @@ protected override Expression VisitSubQuery(SubQueryExpression expression)

private static ReadonlyNodeTypeProvider CreateNodeTypeProvider()
{
var methodInfoBasedNodeTypeRegistry = MethodInfoBasedNodeTypeRegistry.CreateFromRemotionLinqAssembly();
var methodInfoBasedNodeTypeRegistry = MethodInfoBasedNodeTypeRegistry.CreateFromRelinqAssembly();

methodInfoBasedNodeTypeRegistry
.Register(QueryAnnotationExpressionNode.SupportedMethods, typeof(QueryAnnotationExpressionNode));
Expand All @@ -262,7 +267,7 @@ var innerProviders
= new INodeTypeProvider[]
{
methodInfoBasedNodeTypeRegistry,
MethodNameBasedNodeTypeRegistry.CreateFromRemotionLinqAssembly()
MethodNameBasedNodeTypeRegistry.CreateFromRelinqAssembly()
};

return new ReadonlyNodeTypeProvider(new CompoundNodeTypeProvider(innerProviders));
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -11,25 +11,25 @@
using Microsoft.Data.Entity.Utilities;
using Remotion.Linq.Clauses;
using Remotion.Linq.Clauses.Expressions;
using Remotion.Linq.Clauses.ExpressionVisitors;
using Remotion.Linq.Parsing;

namespace Microsoft.Data.Entity.Query.ExpressionVisitors
{
public class MemberAccessBindingExpressionVisitor : ReferenceReplacingExpressionVisitor
public class MemberAccessBindingExpressionVisitor : RelinqExpressionVisitor
{
private readonly QuerySourceMapping _querySourceMapping;
private readonly EntityQueryModelVisitor _queryModelVisitor;
private readonly bool _inProjection;

public MemberAccessBindingExpressionVisitor(
[NotNull] QuerySourceMapping querySourceMapping,
[NotNull] EntityQueryModelVisitor queryModelVisitor,
bool inProjection)
: base(
Check.NotNull(querySourceMapping, nameof(querySourceMapping)),
throwOnUnmappedReferences: false)
{
Check.NotNull(querySourceMapping, nameof(querySourceMapping));
Check.NotNull(queryModelVisitor, nameof(queryModelVisitor));

_querySourceMapping = querySourceMapping;
_queryModelVisitor = queryModelVisitor;
_inProjection = inProjection;
}
Expand Down Expand Up @@ -81,9 +81,9 @@ protected override Expression VisitQuerySourceReference(QuerySourceReferenceExpr
Check.NotNull(querySourceReferenceExpression, nameof(querySourceReferenceExpression));

var newExpression
= QuerySourceMapping.ContainsMapping(querySourceReferenceExpression.ReferencedQuerySource)
? QuerySourceMapping.GetExpression(querySourceReferenceExpression.ReferencedQuerySource)
: base.VisitQuerySourceReference(querySourceReferenceExpression);
= _querySourceMapping.ContainsMapping(querySourceReferenceExpression.ReferencedQuerySource)
? _querySourceMapping.GetExpression(querySourceReferenceExpression.ReferencedQuerySource)
: querySourceReferenceExpression;

if (_inProjection
&& newExpression.Type.IsConstructedGenericType)
Expand Down Expand Up @@ -111,6 +111,12 @@ var newExpression
return newExpression;
}

protected override Expression VisitSubQuery(SubQueryExpression expression)
{
expression.QueryModel.TransformExpressions(Visit);
return expression;
}

protected override Expression VisitMember(MemberExpression memberExpression)
{
Check.NotNull(memberExpression, nameof(memberExpression));
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -15,10 +15,11 @@ public class ParameterExtractingExpressionVisitor : ExpressionVisitorBase
{
public static Expression ExtractParameters(
[NotNull] Expression expressionTree,
[NotNull] QueryContext queryContext)
[NotNull] QueryContext queryContext,
[NotNull] IEvaluatableExpressionFilter evaluatableExpressionFilter)
{
var functionEvaluationDisabledExpression = new FunctionEvaluationDisablingVisitor().Visit(expressionTree);
var partialEvaluationInfo = EvaluatableTreeFindingExpressionVisitor.Analyze(functionEvaluationDisabledExpression);
var partialEvaluationInfo = EvaluatableTreeFindingExpressionVisitor.Analyze(functionEvaluationDisabledExpression, evaluatableExpressionFilter);
var visitor = new ParameterExtractingExpressionVisitor(partialEvaluationInfo, queryContext);

return visitor.Visit(functionEvaluationDisabledExpression);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -25,16 +25,6 @@ public MethodCallEvaluationPreventingExpression([NotNull] MethodCallExpression a

public override Type Type => _methodCall.Type;

public override bool CanReduce
{
get { return true; }
}

public override Expression Reduce()
{
return MethodCall;
}

protected override Expression VisitChildren(ExpressionVisitor visitor)
{
var newObject = visitor.Visit(MethodCall.Object);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -22,16 +22,6 @@ public PropertyEvaluationPreventingExpression([NotNull] MemberExpression argumen

public override Type Type => _memberExpression.Type;

public override bool CanReduce
{
get { return true; }
}

public override Expression Reduce()
{
return MemberExpression;
}

protected override Expression VisitChildren(ExpressionVisitor visitor)
{
var newExpression = visitor.Visit(MemberExpression.Expression);
Expand Down
47 changes: 41 additions & 6 deletions src/EntityFramework7.Core/Query/QueryOptimizer.cs
Original file line number Diff line number Diff line change
@@ -1,8 +1,10 @@
// Copyright (c) .NET Foundation. All rights reserved.
// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.

using System;
using System.Collections.Generic;
using System.Linq;
using System.Linq.Expressions;
using JetBrains.Annotations;
using Microsoft.Data.Entity.Query.Annotations;
using Microsoft.Data.Entity.Utilities;
Expand All @@ -17,6 +19,32 @@ namespace Microsoft.Data.Entity.Query
{
public class QueryOptimizer : SubQueryFromClauseFlattener
{
private class FromClauseData : IFromClause
{
public string ItemName { get; }

public Type ItemType { get; }

public Expression FromExpression { get; }

public FromClauseData(string itemName, Type itemType, Expression fromExpression)
{
ItemName = itemName;
ItemType = itemType;
FromExpression = fromExpression;
}

void IClause.TransformExpressions(Func<Expression, Expression> transformation)
{
throw new NotSupportedException();
}

void IFromClause.CopyFromSource(IFromClause source)
{
throw new NotSupportedException();
}
}

private readonly IReadOnlyCollection<QueryAnnotationBase> _queryAnnotations;

public QueryOptimizer([NotNull] IReadOnlyCollection<QueryAnnotationBase> queryAnnotations)
Expand Down Expand Up @@ -57,7 +85,7 @@ in _queryAnnotations

protected override void FlattenSubQuery(
[NotNull] SubQueryExpression subQueryExpression,
[NotNull] FromClauseBase fromClause,
[NotNull] IFromClause fromClause,
[NotNull] QueryModel queryModel,
int destinationIndex)
{
Expand All @@ -75,18 +103,25 @@ protected override void FlattenSubQuery(
|| (queryModel.IsIdentityQuery()
&& !queryModel.ResultOperators.Any()))
{
string itemName;
var innerMainFromClause = subQueryExpression.QueryModel.MainFromClause;

var isGeneratedNameOuter = fromClause.HasGeneratedItemName();
var outerItemName = fromClause.ItemName;
CopyFromClauseData(innerMainFromClause, fromClause);

if (innerMainFromClause.HasGeneratedItemName()
&& !isGeneratedNameOuter)
{
fromClause.ItemName = outerItemName;
itemName = fromClause.ItemName;
}
else
{
itemName = innerMainFromClause.ItemName;
}

var fromClauseData = new FromClauseData(
itemName,
innerMainFromClause.ItemType,
innerMainFromClause.FromExpression);
fromClause.CopyFromSource(fromClauseData);

var innerSelectorMapping = new QuerySourceMapping();

innerSelectorMapping.AddMapping(fromClause, subQueryExpression.QueryModel.SelectClause.Selector);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,7 @@ public ThenIncludeExpressionNode(
_navigationPropertyPathLambda = navigationPropertyPathLambda;
}

protected override QueryModel ApplyNodeSpecificSemantics(QueryModel queryModel, ClauseGenerationContext clauseGenerationContext)
protected override void ApplyNodeSpecificSemantics(QueryModel queryModel, ClauseGenerationContext clauseGenerationContext)
{
var queryAnnotationResultOperator
= (QueryAnnotationResultOperator)clauseGenerationContext.GetContextInfo(Source);
Expand All @@ -41,8 +41,6 @@ var queryAnnotationResultOperator
.AppendToNavigationPath(_navigationPropertyPathLambda.GetComplexPropertyAccess());

clauseGenerationContext.AddContextInfo(this, queryAnnotationResultOperator);

return queryModel;
}

protected override ResultOperatorBase CreateResultOperator(ClauseGenerationContext clauseGenerationContext) => null;
Expand Down
2 changes: 1 addition & 1 deletion src/EntityFramework7.Core/project.json
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@
"Microsoft.Framework.Logging": "1.0.0-*",
"Microsoft.Framework.Logging.Abstractions": "1.0.0-*",
"Microsoft.Framework.OptionsModel": "1.0.0-*",
"Remotion.Linq": "2.0.0-alpha-004",
"Remotion.Linq": "2.0.0-beta-002",
"System.Collections.Immutable": "1.1.37-*"
},
"compile": "..\\Shared\\*.cs",
Expand Down