Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Annotate query for NRT #23185

Merged
1 commit merged into from
Nov 4, 2020
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 @@ -11,6 +11,8 @@
using Microsoft.EntityFrameworkCore.Query;
using Microsoft.EntityFrameworkCore.Utilities;

#nullable enable

namespace Microsoft.EntityFrameworkCore.InMemory.Query.Internal
{
/// <summary>
Expand Down Expand Up @@ -55,7 +57,7 @@ public EntityProjectionExpression(
/// doing so can result in application failures when updating to a new Entity Framework Core release.
/// </summary>
public override Type Type
=> EntityType.ClrType;
=> EntityType.ClrType!;

/// <summary>
/// This is an internal API that supports the Entity Framework Core infrastructure and not subject to
Expand Down Expand Up @@ -137,7 +139,7 @@ public virtual void AddNavigationBinding([NotNull] INavigation navigation, [NotN
/// any release. You should only use it directly in your code with extreme caution and knowing that
/// doing so can result in application failures when updating to a new Entity Framework Core release.
/// </summary>
public virtual EntityShaperExpression BindNavigation([NotNull] INavigation navigation)
public virtual EntityShaperExpression? BindNavigation([NotNull] INavigation navigation)
{
if (!EntityType.IsAssignableFrom(navigation.DeclaringEntityType)
&& !navigation.DeclaringEntityType.IsAssignableFrom(EntityType))
Expand Down

Large diffs are not rendered by default.

Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,8 @@
using Microsoft.EntityFrameworkCore.Storage;
using Microsoft.EntityFrameworkCore.Utilities;

#nullable enable

namespace Microsoft.EntityFrameworkCore.InMemory.Query.Internal
{
/// <summary>
Expand Down Expand Up @@ -46,6 +48,7 @@ public InMemoryProjectionBindingExpressionVisitor(
{
_queryableMethodTranslatingExpressionVisitor = queryableMethodTranslatingExpressionVisitor;
_expressionTranslatingExpressionVisitor = expressionTranslatingExpressionVisitor;
_queryExpression = null!;
}

/// <summary>
Expand Down Expand Up @@ -75,11 +78,11 @@ public virtual Expression Translate([NotNull] InMemoryQueryExpression queryExpre
}

_queryExpression.ReplaceProjectionMapping(_projectionMapping);
_queryExpression = null;
_queryExpression = null!;
_projectionMapping.Clear();
_projectionMembers.Clear();

result = MatchTypes(result, expression.Type);
result = MatchTypes(result!, expression.Type);

return result;
}
Expand All @@ -90,7 +93,7 @@ public virtual Expression Translate([NotNull] InMemoryQueryExpression queryExpre
/// any release. You should only use it directly in your code with extreme caution and knowing that
/// doing so can result in application failures when updating to a new Entity Framework Core release.
/// </summary>
public override Expression Visit(Expression expression)
public override Expression? Visit(Expression? expression)
{
if (expression == null)
{
Expand Down Expand Up @@ -120,9 +123,9 @@ public override Expression Visit(Expression expression)
case MaterializeCollectionNavigationExpression materializeCollectionNavigationExpression:
return AddCollectionProjection(
_queryableMethodTranslatingExpressionVisitor.TranslateSubquery(
materializeCollectionNavigationExpression.Subquery),
materializeCollectionNavigationExpression.Subquery)!,
materializeCollectionNavigationExpression.Navigation,
materializeCollectionNavigationExpression.Navigation.ClrType.TryGetSequenceType());
materializeCollectionNavigationExpression.Navigation.ClrType.TryGetSequenceType()!);

case MethodCallExpression methodCallExpression:
{
Expand Down Expand Up @@ -196,8 +199,8 @@ public override Expression Visit(Expression expression)
/// </summary>
protected override Expression VisitBinary(BinaryExpression binaryExpression)
{
var left = MatchTypes(Visit(binaryExpression.Left), binaryExpression.Left.Type);
var right = MatchTypes(Visit(binaryExpression.Right), binaryExpression.Right.Type);
var left = MatchTypes(Visit(binaryExpression.Left)!, binaryExpression.Left.Type);
var right = MatchTypes(Visit(binaryExpression.Right)!, binaryExpression.Right.Type);

return binaryExpression.Update(left, VisitAndConvert(binaryExpression.Conversion, "VisitBinary"), right);
}
Expand All @@ -210,9 +213,9 @@ protected override Expression VisitBinary(BinaryExpression binaryExpression)
/// </summary>
protected override Expression VisitConditional(ConditionalExpression conditionalExpression)
{
var test = Visit(conditionalExpression.Test);
var ifTrue = Visit(conditionalExpression.IfTrue);
var ifFalse = Visit(conditionalExpression.IfFalse);
var test = Visit(conditionalExpression.Test)!;
smitpatel marked this conversation as resolved.
Show resolved Hide resolved
var ifTrue = Visit(conditionalExpression.IfTrue)!;
var ifFalse = Visit(conditionalExpression.IfFalse)!;

if (test.Type == typeof(bool?))
{
Expand All @@ -228,7 +231,7 @@ protected override Expression VisitConditional(ConditionalExpression conditional
/// any release. You should only use it directly in your code with extreme caution and knowing that
/// doing so can result in application failures when updating to a new Entity Framework Core release.
/// </summary>
protected override Expression VisitExtension(Expression extensionExpression)
protected override Expression? VisitExtension(Expression extensionExpression)
{
Check.NotNull(extensionExpression, nameof(extensionExpression));

Expand All @@ -237,6 +240,12 @@ protected override Expression VisitExtension(Expression extensionExpression)
EntityProjectionExpression entityProjectionExpression;
if (entityShaperExpression.ValueBufferExpression is ProjectionBindingExpression projectionBindingExpression)
{
if (projectionBindingExpression.ProjectionMember == null)
{
// We don't process binding with client projection
return null;
}

entityProjectionExpression = (EntityProjectionExpression)((InMemoryQueryExpression)projectionBindingExpression.QueryExpression)
.GetMappedProjection(projectionBindingExpression.ProjectionMember);
}
Expand Down Expand Up @@ -274,7 +283,7 @@ protected override Expression VisitExtension(Expression extensionExpression)
/// doing so can result in application failures when updating to a new Entity Framework Core release.
/// </summary>
protected override ElementInit VisitElementInit(ElementInit elementInit)
=> elementInit.Update(elementInit.Arguments.Select(e => MatchTypes(Visit(e), e.Type)));
=> elementInit.Update(elementInit.Arguments.Select(e => MatchTypes(Visit(e)!, e.Type)));

/// <summary>
/// This is an internal API that supports the Entity Framework Core infrastructure and not subject to
Expand Down Expand Up @@ -311,10 +320,10 @@ protected override Expression VisitMember(MemberExpression memberExpression)
/// any release. You should only use it directly in your code with extreme caution and knowing that
/// doing so can result in application failures when updating to a new Entity Framework Core release.
/// </summary>
protected override MemberAssignment VisitMemberAssignment(MemberAssignment memberAssignment)
protected override MemberAssignment? VisitMemberAssignment(MemberAssignment memberAssignment)
{
var expression = memberAssignment.Expression;
Expression visitedExpression;
Expression? visitedExpression;
if (_clientEval)
{
visitedExpression = Visit(memberAssignment.Expression);
Expand All @@ -333,7 +342,7 @@ protected override MemberAssignment VisitMemberAssignment(MemberAssignment membe
_projectionMembers.Pop();
}

visitedExpression = MatchTypes(visitedExpression, expression.Type);
visitedExpression = MatchTypes(visitedExpression!, expression.Type);

return memberAssignment.Update(visitedExpression);
}
Expand All @@ -344,7 +353,7 @@ protected override MemberAssignment VisitMemberAssignment(MemberAssignment membe
/// any release. You should only use it directly in your code with extreme caution and knowing that
/// doing so can result in application failures when updating to a new Entity Framework Core release.
/// </summary>
protected override Expression VisitMemberInit(MemberInitExpression memberInitExpression)
protected override Expression? VisitMemberInit(MemberInitExpression memberInitExpression)
{
Check.NotNull(memberInitExpression, nameof(memberInitExpression));

Expand Down Expand Up @@ -385,7 +394,7 @@ protected override Expression VisitMethodCall(MethodCallExpression methodCallExp
for (var i = 0; i < methodCallExpression.Arguments.Count; i++)
{
var argument = methodCallExpression.Arguments[i];
arguments[i] = MatchTypes(Visit(argument), argument.Type);
arguments[i] = MatchTypes(Visit(argument)!, argument.Type);
}

Expression updatedMethodCallExpression = methodCallExpression.Update(
Expand Down Expand Up @@ -416,7 +425,7 @@ protected override Expression VisitMethodCall(MethodCallExpression methodCallExp
/// any release. You should only use it directly in your code with extreme caution and knowing that
/// doing so can result in application failures when updating to a new Entity Framework Core release.
/// </summary>
protected override Expression VisitNew(NewExpression newExpression)
protected override Expression? VisitNew(NewExpression newExpression)
{
Check.NotNull(newExpression, nameof(newExpression));

Expand All @@ -435,7 +444,7 @@ protected override Expression VisitNew(NewExpression newExpression)
for (var i = 0; i < newArguments.Length; i++)
{
var argument = newExpression.Arguments[i];
Expression visitedArgument;
Expression? visitedArgument;
if (_clientEval)
{
visitedArgument = Visit(argument);
Expand All @@ -453,7 +462,7 @@ protected override Expression VisitNew(NewExpression newExpression)
_projectionMembers.Pop();
}

newArguments[i] = MatchTypes(visitedArgument, argument.Type);
newArguments[i] = MatchTypes(visitedArgument!, argument.Type);
}

return newExpression.Update(newArguments);
Expand All @@ -466,7 +475,7 @@ protected override Expression VisitNew(NewExpression newExpression)
/// doing so can result in application failures when updating to a new Entity Framework Core release.
/// </summary>
protected override Expression VisitNewArray(NewArrayExpression newArrayExpression)
=> newArrayExpression.Update(newArrayExpression.Expressions.Select(e => MatchTypes(Visit(e), e.Type)));
=> newArrayExpression.Update(newArrayExpression.Expressions.Select(e => MatchTypes(Visit(e)!, e.Type)));

/// <summary>
/// This is an internal API that supports the Entity Framework Core infrastructure and not subject to
Expand All @@ -476,7 +485,7 @@ protected override Expression VisitNewArray(NewArrayExpression newArrayExpressio
/// </summary>
protected override Expression VisitUnary(UnaryExpression unaryExpression)
{
var operand = Visit(unaryExpression.Operand);
var operand = Visit(unaryExpression.Operand)!;

return (unaryExpression.NodeType == ExpressionType.Convert
|| unaryExpression.NodeType == ExpressionType.ConvertChecked)
Expand All @@ -487,7 +496,7 @@ protected override Expression VisitUnary(UnaryExpression unaryExpression)

private CollectionShaperExpression AddCollectionProjection(
ShapedQueryExpression subquery,
INavigationBase navigation,
INavigationBase? navigation,
Type elementType)
=> new CollectionShaperExpression(
new ProjectionBindingExpression(
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,8 @@
using System.Collections.Generic;
using Microsoft.EntityFrameworkCore.Storage;

#nullable enable

namespace Microsoft.EntityFrameworkCore.InMemory.Query.Internal
{
public partial class InMemoryQueryExpression
Expand Down
15 changes: 9 additions & 6 deletions src/EFCore.InMemory/Query/Internal/InMemoryQueryExpression.cs
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,8 @@
using Microsoft.EntityFrameworkCore.Utilities;
using ExpressionExtensions = Microsoft.EntityFrameworkCore.Infrastructure.ExpressionExtensions;

#nullable enable

namespace Microsoft.EntityFrameworkCore.InMemory.Query.Internal
{
/// <summary>
Expand All @@ -40,7 +42,7 @@ private readonly IDictionary<EntityProjectionExpression, IDictionary<IProperty,
private readonly ParameterExpression _valueBufferParameter;

private IDictionary<ProjectionMember, Expression> _projectionMapping = new Dictionary<ProjectionMember, Expression>();
private ParameterExpression _groupingParameter;
private ParameterExpression? _groupingParameter;

/// <summary>
/// This is an internal API that supports the Entity Framework Core infrastructure and not subject to
Expand Down Expand Up @@ -98,6 +100,7 @@ public InMemoryQueryExpression([NotNull] IEntityType entityType)
ServerQueryExpression = new InMemoryTableExpression(entityType);
var readExpressionMap = new Dictionary<IProperty, Expression>();
var discriminatorProperty = entityType.GetDiscriminatorProperty();
var keyValueComparer = discriminatorProperty?.GetKeyValueComparer();
foreach (var property in entityType.GetAllBaseTypesInclusive().SelectMany(et => et.GetDeclaredProperties()))
{
readExpressionMap[property] = CreateReadValueExpression(property.ClrType, property.GetIndex(), property);
Expand All @@ -107,9 +110,9 @@ public InMemoryQueryExpression([NotNull] IEntityType entityType)
{
var entityCheck = derivedEntityType.GetConcreteDerivedTypesInclusive()
.Select(
e => discriminatorProperty.GetKeyValueComparer().ExtractEqualsBody(
readExpressionMap[discriminatorProperty],
Constant(e.GetDiscriminatorValue(), discriminatorProperty.ClrType)))
e => keyValueComparer!.ExtractEqualsBody(
readExpressionMap[discriminatorProperty!],
Constant(e.GetDiscriminatorValue(), discriminatorProperty!.ClrType)))
.Aggregate((l, r) => OrElse(l, r));

foreach (var property in derivedEntityType.GetDeclaredProperties())
Expand Down Expand Up @@ -436,7 +439,7 @@ public virtual void ApplyDefaultIfEmpty()
_valueBufferSlots.Clear();
}

private static IPropertyBase InferPropertyFromInner(Expression expression)
private static IPropertyBase? InferPropertyFromInner(Expression expression)
=> expression is MethodCallExpression methodCallExpression
&& methodCallExpression.Method.IsGenericMethod
&& methodCallExpression.Method.GetGenericMethodDefinition() == ExpressionExtensions.ValueBufferTryReadValueMethod
Expand Down Expand Up @@ -576,7 +579,7 @@ private Expression GetGroupingKey(Expression key, List<Expression> groupingExpre
}
}

private Expression CreateReadValueExpression(Type type, int index, IPropertyBase property)
private Expression CreateReadValueExpression(Type type, int index, IPropertyBase? property)
=> _valueBufferParameter.CreateValueBufferReadValueExpression(type, index, property);

/// <summary>
Expand Down
Loading