diff --git a/src/EFCore.Relational/Query/RelationalEntityShaperExpression.cs b/src/EFCore.Relational/Query/RelationalEntityShaperExpression.cs index ce2d2bcbef3..6b114042c6e 100644 --- a/src/EFCore.Relational/Query/RelationalEntityShaperExpression.cs +++ b/src/EFCore.Relational/Query/RelationalEntityShaperExpression.cs @@ -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)) { } @@ -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; } } diff --git a/src/EFCore/Properties/CoreStrings.Designer.cs b/src/EFCore/Properties/CoreStrings.Designer.cs index 6402d3956f7..97c5c8eb221 100644 --- a/src/EFCore/Properties/CoreStrings.Designer.cs +++ b/src/EFCore/Properties/CoreStrings.Designer.cs @@ -2578,6 +2578,14 @@ public static string FunctionOnClient([CanBeNull] object methodName) GetString("FunctionOnClient", nameof(methodName)), methodName); + /// + /// Materialization condition passed for entity shaper of entity type '{entityType}' is not of correct shape. Materialization condition must be LambdaExpression of 'Func<ValueBuffer, IEntityType>' + /// + public static string QueryEntityMaterializationConditionWrongShape([CanBeNull] object entityType) + => string.Format( + GetString("QueryEntityMaterializationConditionWrongShape", nameof(entityType)), + entityType); + private static string GetString(string name, params string[] formatterNames) { var value = _resourceManager.GetString(name); diff --git a/src/EFCore/Properties/CoreStrings.resx b/src/EFCore/Properties/CoreStrings.resx index 9701fad6b53..1848bc401fb 100644 --- a/src/EFCore/Properties/CoreStrings.resx +++ b/src/EFCore/Properties/CoreStrings.resx @@ -1363,4 +1363,7 @@ 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. + + Materialization condition passed for entity shaper of entity type '{entityType}' is not of correct shape. Materialization condition must be LambdaExpression of 'Func<ValueBuffer, IEntityType>' + \ No newline at end of file diff --git a/src/EFCore/Query/EntityShaperExpression.cs b/src/EFCore/Query/EntityShaperExpression.cs index d0e34bedd61..8b417397fde 100644 --- a/src/EFCore/Query/EntityShaperExpression.cs +++ b/src/EFCore/Query/EntityShaperExpression.cs @@ -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."); + 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; @@ -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) { @@ -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; @@ -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; } diff --git a/src/EFCore/Query/ShapedQueryCompilingExpressionVisitor.cs b/src/EFCore/Query/ShapedQueryCompilingExpressionVisitor.cs index 0609ec8ba49..bdabc2ac0f5 100644 --- a/src/EFCore/Query/ShapedQueryCompilingExpressionVisitor.cs +++ b/src/EFCore/Query/ShapedQueryCompilingExpressionVisitor.cs @@ -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(); @@ -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())); } } }