From 434a75a63ef50dc192b0b8792529ec09bb0bee8d Mon Sep 17 00:00:00 2001 From: Shay Rojansky Date: Fri, 15 Sep 2023 20:51:41 +0300 Subject: [PATCH] Allow generating EF.Property over struct (#31753) Fixes #31610 --- src/EFCore/EF.cs | 6 +++--- src/EFCore/Infrastructure/ExpressionExtensions.cs | 7 +++++++ 2 files changed, 10 insertions(+), 3 deletions(-) diff --git a/src/EFCore/EF.cs b/src/EFCore/EF.cs index 60f05cddaca..76b7c5b4880 100644 --- a/src/EFCore/EF.cs +++ b/src/EFCore/EF.cs @@ -41,7 +41,7 @@ internal static MethodInfo MakePropertyMethod(Type type) public static bool IsDesignTime { get; set; } /// - /// References a given property or navigation on an entity instance. This is useful for shadow state properties, for + /// References a given property or navigation on an entity or complex type instance. This is useful for shadow state properties, for /// which no CLR property exists. Currently this method can only be used in LINQ queries and can not be used to /// access the value assigned to a property in other scenarios. /// @@ -54,11 +54,11 @@ internal static MethodInfo MakePropertyMethod(Type type) /// /// /// The type of the property being referenced. - /// The entity to access the property on. + /// The entity or complex type to access the property on. /// The name of the property. /// The value assigned to the property. public static TProperty Property( - object entity, + object instance, [NotParameterized] string propertyName) => throw new InvalidOperationException(CoreStrings.PropertyMethodInvoked); diff --git a/src/EFCore/Infrastructure/ExpressionExtensions.cs b/src/EFCore/Infrastructure/ExpressionExtensions.cs index e2764778894..8d47e09064d 100644 --- a/src/EFCore/Infrastructure/ExpressionExtensions.cs +++ b/src/EFCore/Infrastructure/ExpressionExtensions.cs @@ -384,6 +384,13 @@ private static Expression CreateEFPropertyExpression( propertyType = propertyType.MakeNullable(); } + // EF.Property expects an object as its first argument. If the target is a struct (complex type), we need an explicit up-cast to + // object. + if (target.Type.IsValueType) + { + target = Expression.Convert(target, typeof(object)); + } + return Expression.Call( EF.MakePropertyMethod(propertyType), target,