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

Query: Cleanup in optional dependent SQL feature #20354

Merged
merged 1 commit into from
Mar 20, 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 @@ -35,9 +35,9 @@ public RelationalEntityShaperExpression(
[NotNull] IEntityType entityType,
[NotNull] Expression valueBufferExpression,
bool nullable,
[NotNull] LambdaExpression discriminatorCondition)
[CanBeNull] LambdaExpression materializationCondition)
: base(entityType, valueBufferExpression, nullable,
discriminatorCondition ?? GenerateMaterializationCondition(Check.NotNull(entityType, nameof(entityType)), nullable))
materializationCondition ?? GenerateMaterializationCondition(Check.NotNull(entityType, nameof(entityType)), nullable))
{
}

Expand Down Expand Up @@ -157,7 +157,7 @@ public override EntityShaperExpression Update(Expression valueBufferExpression)
Check.NotNull(valueBufferExpression, nameof(valueBufferExpression));

return valueBufferExpression != ValueBufferExpression
? new RelationalEntityShaperExpression(EntityType, valueBufferExpression, IsNullable, DiscriminatorCondition)
? new RelationalEntityShaperExpression(EntityType, valueBufferExpression, IsNullable, MaterializationCondition)
: this;
}
}
Expand Down
8 changes: 8 additions & 0 deletions src/EFCore/Properties/CoreStrings.Designer.cs

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

3 changes: 3 additions & 0 deletions src/EFCore/Properties/CoreStrings.resx
Original file line number Diff line number Diff line change
Expand Up @@ -1363,4 +1363,7 @@
<data name="FunctionOnClient" xml:space="preserve">
<value>The '{methodName}' method is not supported because the query has switched to client-evaluation. Inspect the log to determine which query expressions are triggering client-evaluation.</value>
</data>
<data name="QueryEntityMaterializationConditionWrongShape" xml:space="preserve">
<value>Materialization condition passed for entity shaper of entity type '{entityType}' is not of correct shape. Materialization condition must be LambdaExpression of 'Func&lt;ValueBuffer, IEntityType&gt;'</value>
</data>
</root>
25 changes: 12 additions & 13 deletions src/EFCore/Query/EntityShaperExpression.cs
Original file line number Diff line number Diff line change
Expand Up @@ -38,30 +38,29 @@ protected EntityShaperExpression(
[NotNull] IEntityType entityType,
[NotNull] Expression valueBufferExpression,
bool nullable,
[CanBeNull] LambdaExpression discriminatorCondition)
[CanBeNull] LambdaExpression materializationCondition)
{
Check.NotNull(entityType, nameof(entityType));
Check.NotNull(valueBufferExpression, nameof(valueBufferExpression));

if (discriminatorCondition == null)
if (materializationCondition == null)
{
discriminatorCondition = GenerateDiscriminatorCondition(entityType, nullable);
materializationCondition = GenerateMaterializationCondition(entityType, nullable);
}
else if (discriminatorCondition.Parameters.Count != 1
|| discriminatorCondition.Parameters[0].Type != typeof(ValueBuffer)
|| discriminatorCondition.ReturnType != typeof(IEntityType))
else if (materializationCondition.Parameters.Count != 1
|| materializationCondition.Parameters[0].Type != typeof(ValueBuffer)
|| materializationCondition.ReturnType != typeof(IEntityType))
{
throw new InvalidOperationException(
"Discriminator condition must be lambda expression of type Func<ValueBuffer, IEntityType>.");
throw new InvalidOperationException(CoreStrings.QueryEntityMaterializationConditionWrongShape(entityType.DisplayName()));
}

EntityType = entityType;
ValueBufferExpression = valueBufferExpression;
IsNullable = nullable;
DiscriminatorCondition = discriminatorCondition;
MaterializationCondition = materializationCondition;
}

private LambdaExpression GenerateDiscriminatorCondition(IEntityType entityType, bool nullable)
private LambdaExpression GenerateMaterializationCondition(IEntityType entityType, bool nullable)
{
var valueBufferParameter = Parameter(typeof(ValueBuffer));
Expression body;
Expand Down Expand Up @@ -117,7 +116,7 @@ private LambdaExpression GenerateDiscriminatorCondition(IEntityType entityType,
public virtual IEntityType EntityType { get; }
public virtual Expression ValueBufferExpression { get; }
public virtual bool IsNullable { get; }
public virtual LambdaExpression DiscriminatorCondition { get; }
public virtual LambdaExpression MaterializationCondition { get; }

protected override Expression VisitChildren(ExpressionVisitor visitor)
{
Expand All @@ -139,7 +138,7 @@ public virtual EntityShaperExpression WithEntityType([NotNull] IEntityType entit

public virtual EntityShaperExpression MarkAsNullable()
=> !IsNullable
// Marking nullable requires recomputation of Discriminator condition
// Marking nullable requires recomputation of materialization condition
? new EntityShaperExpression(EntityType, ValueBufferExpression, true)
: this;

Expand All @@ -148,7 +147,7 @@ public virtual EntityShaperExpression Update([NotNull] Expression valueBufferExp
Check.NotNull(valueBufferExpression, nameof(valueBufferExpression));

return valueBufferExpression != ValueBufferExpression
? new EntityShaperExpression(EntityType, valueBufferExpression, IsNullable, DiscriminatorCondition)
? new EntityShaperExpression(EntityType, valueBufferExpression, IsNullable, MaterializationCondition)
: this;
}

Expand Down
12 changes: 2 additions & 10 deletions src/EFCore/Query/ShapedQueryCompilingExpressionVisitor.cs
Original file line number Diff line number Diff line change
Expand Up @@ -452,9 +452,9 @@ private Expression MaterializeEntity(
expressions.Add(
Expression.Assign(concreteEntityTypeVariable,
ReplacingExpressionVisitor.Replace(
entityShaperExpression.DiscriminatorCondition.Parameters[0],
entityShaperExpression.MaterializationCondition.Parameters[0],
valueBufferExpression,
entityShaperExpression.DiscriminatorCondition.Body)));
entityShaperExpression.MaterializationCondition.Body)));

var concreteEntityTypes = entityType.GetConcreteDerivedTypesInclusive().ToArray();
var discriminatorProperty = entityType.GetDiscriminatorProperty();
Expand Down Expand Up @@ -550,14 +550,6 @@ private BlockExpression CreateFullMaterializeExpression(

return Expression.Block(blockExpressions);
}

private static readonly MethodInfo _createUnableToDiscriminateException
= typeof(EntityMaterializerInjectingExpressionVisitor).GetTypeInfo()
.GetDeclaredMethod(nameof(CreateUnableToDiscriminateException));

[UsedImplicitly]
private static Exception CreateUnableToDiscriminateException(IEntityType entityType, object discriminator)
=> new InvalidOperationException(CoreStrings.UnableToDiscriminate(entityType.DisplayName(), discriminator?.ToString()));
}
}
}