Skip to content

Commit

Permalink
Generate conditionals instead of switch in materializer delegate for …
Browse files Browse the repository at this point in the history
…discriminator values that need custom comparison (#22470)

Part of #19650
  • Loading branch information
ajcvickers committed Sep 10, 2020
1 parent 69ce8af commit 77c16b4
Show file tree
Hide file tree
Showing 2 changed files with 21 additions and 54 deletions.
40 changes: 21 additions & 19 deletions src/EFCore/Query/EntityShaperExpression.cs
Original file line number Diff line number Diff line change
Expand Up @@ -111,40 +111,42 @@ protected virtual LambdaExpression GenerateMaterializationCondition([NotNull] IE
discriminatorProperty.ClrType, discriminatorProperty.GetIndex(), discriminatorProperty))
};

var switchCases = new SwitchCase[concreteEntityTypes.Length];
for (var i = 0; i < concreteEntityTypes.Length; i++)
{
var discriminatorValue = Constant(concreteEntityTypes[i].GetDiscriminatorValue(), discriminatorProperty.ClrType);
switchCases[i] = SwitchCase(Constant(concreteEntityTypes[i], typeof(IEntityType)), discriminatorValue);
}

var exception = Block(
Throw(
Call(
_createUnableToDiscriminateException, Constant(entityType),
Convert(discriminatorValueVariable, typeof(object)))),
Constant(null, typeof(IEntityType)));


var discriminatorComparer = discriminatorProperty.GetKeyValueComparer();
if (discriminatorComparer.IsDefault())
{
var switchCases = new SwitchCase[concreteEntityTypes.Length];
for (var i = 0; i < concreteEntityTypes.Length; i++)
{
var discriminatorValue = Constant(concreteEntityTypes[i].GetDiscriminatorValue(), discriminatorProperty.ClrType);
switchCases[i] = SwitchCase(Constant(concreteEntityTypes[i], typeof(IEntityType)), discriminatorValue);
}

expressions.Add(Switch(discriminatorValueVariable, exception, switchCases));
}
else
{
var staticComparer = typeof(StaticDiscriminatorComparer<,,>).MakeGenericType(
discriminatorProperty.DeclaringEntityType.ClrType,
discriminatorProperty.ClrType,
discriminatorProperty.GetTypeMapping().Converter.ProviderClrType);

var comparerField = staticComparer.GetField(nameof(StaticDiscriminatorComparer<int, int, int>.Comparer));
comparerField.SetValue(null, discriminatorComparer);

var equalsMethod = staticComparer.GetMethod(nameof(StaticDiscriminatorComparer<int, int, int>.DiscriminatorEquals));
expressions.Add(Switch(discriminatorValueVariable, exception, equalsMethod, switchCases));
Expression conditions = exception;
for (var i = concreteEntityTypes.Length - 1; i >= 0; i--)
{
conditions = Condition(
discriminatorComparer.ExtractEqualsBody(
discriminatorValueVariable,
Constant(
concreteEntityTypes[i].GetDiscriminatorValue(),
discriminatorProperty.ClrType)),
Constant(concreteEntityTypes[i], typeof(IEntityType)),
conditions);
}

expressions.Add(conditions);
}

body = Block(new[] { discriminatorValueVariable }, expressions);
}
else
Expand Down
35 changes: 0 additions & 35 deletions src/EFCore/Query/Internal/StaticDiscriminatorComparer.cs

This file was deleted.

0 comments on commit 77c16b4

Please sign in to comment.