From bbb32c02c000b717339147f8d10be894c894f0c2 Mon Sep 17 00:00:00 2001
From: Arkadii <50463369+kawasaniac@users.noreply.github.com>
Date: Sun, 7 Sep 2025 20:31:36 +0200
Subject: [PATCH 1/2] Proper exception handling for RegisterPrivateAccessor()
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
- Add proper handling when a property’s backing field cannot be inferred or the unsafe accessor cannot be generated.
- Add DesignStrings methods and entries to .resx
Fixes #35219
---
.../Properties/DesignStrings.Designer.cs | 18 ++++++++++++++++++
.../Properties/DesignStrings.resx | 6 ++++++
.../CSharpRuntimeModelCodeGenerator.cs | 8 ++++++--
3 files changed, 30 insertions(+), 2 deletions(-)
diff --git a/src/EFCore.Design/Properties/DesignStrings.Designer.cs b/src/EFCore.Design/Properties/DesignStrings.Designer.cs
index fe7161d90e4..c9f5fcfc6fe 100644
--- a/src/EFCore.Design/Properties/DesignStrings.Designer.cs
+++ b/src/EFCore.Design/Properties/DesignStrings.Designer.cs
@@ -910,6 +910,24 @@ public static string WritingSnapshot(object? file)
GetString("WritingSnapshot", nameof(file)),
file);
+ ///
+ /// Backing field for property could not be inferred.
+ ///
+ public static string CompiledModelBackingFieldNotFound(object? entityType, object? propertyName)
+ => string.Format(
+ GetString("CompiledModelBackingFieldNotFound", nameof(entityType)),
+ entityType,
+ propertyName);
+
+ ///
+ /// Unsafe accessor for property could not be generated.
+ ///
+ public static string CompiledModelUnsafeAccessorNull(object? entityType, object? propertyName)
+ => string.Format(
+ GetString("CompiledModelUnsafeAccessorNull", nameof(entityType)),
+ entityType,
+ propertyName);
+
private static string GetString(string name, params string[] formatterNames)
{
var value = _resourceManager.GetString(name)!;
diff --git a/src/EFCore.Design/Properties/DesignStrings.resx b/src/EFCore.Design/Properties/DesignStrings.resx
index 0ed3a278bd8..0bf58783965 100644
--- a/src/EFCore.Design/Properties/DesignStrings.resx
+++ b/src/EFCore.Design/Properties/DesignStrings.resx
@@ -156,6 +156,9 @@
A compilation must be loaded.
+
+ Backing field for property '{entityType}.{propertyName}' could not be inferred. Use a matching field name or configure with HasField().
+
The entity type '{entityType}' has a custom constructor binding. Compiled model can't be generated, because custom constructor bindings are not supported. Configure the custom constructor binding in '{customize}' in a partial '{className}' class instead.
@@ -168,6 +171,9 @@
The entity type '{entityType}' has a query filter configured. Compiled model can't be generated, because query filters are not supported.
+
+ Unsafe accessor for property '{entityType}.{propertyName}' could not be generated. Ensure the property can be accessed or has a matching backing field.
+
The property '{entityType}.{property}' has a value generator configured. Use '{method}' to configure the value generator factory type.
diff --git a/src/EFCore.Design/Scaffolding/Internal/CSharpRuntimeModelCodeGenerator.cs b/src/EFCore.Design/Scaffolding/Internal/CSharpRuntimeModelCodeGenerator.cs
index 07dbde06d0b..bf2d5c82434 100644
--- a/src/EFCore.Design/Scaffolding/Internal/CSharpRuntimeModelCodeGenerator.cs
+++ b/src/EFCore.Design/Scaffolding/Internal/CSharpRuntimeModelCodeGenerator.cs
@@ -1769,7 +1769,9 @@ private void RegisterPrivateAccessors(
Dictionary> unsafeAccessorTypes,
ref Dictionary? memberAccessReplacements)
{
- var member = property.GetMemberInfo(forMaterialization, forSet);
+ var member = property.GetMemberInfo(forMaterialization, forSet) ?? throw new InvalidOperationException(
+ DesignStrings.CompiledModelBackingFieldNotFound(property.DeclaringType.ShortName(), property.Name));
+
switch (member)
{
case FieldInfo field:
@@ -1799,7 +1801,9 @@ private void RegisterPrivateAccessors(
}
memberAccessReplacements ??= [];
- var methodName = LinqToCSharpSyntaxTranslator.GetUnsafeAccessorName(member);
+
+ var methodName = LinqToCSharpSyntaxTranslator.GetUnsafeAccessorName(member) ?? throw new InvalidOperationException(
+ DesignStrings.CompiledModelUnsafeAccessorNull(property.DeclaringType.ShortName(), property.Name));
var declaringType = member.DeclaringType!;
if (declaringType.IsGenericType
From e14d1e2ae4d324d3a1bd7cf6eee62fd74a0e8010 Mon Sep 17 00:00:00 2001
From: Arkadii <50463369+kawasaniac@users.noreply.github.com>
Date: Thu, 11 Sep 2025 10:20:55 +0200
Subject: [PATCH 2/2] Update src/EFCore.Design/Properties/DesignStrings.resx
Co-authored-by: Andriy Svyryd
---
src/EFCore.Design/Properties/DesignStrings.resx | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/src/EFCore.Design/Properties/DesignStrings.resx b/src/EFCore.Design/Properties/DesignStrings.resx
index 0bf58783965..88fcebc23cf 100644
--- a/src/EFCore.Design/Properties/DesignStrings.resx
+++ b/src/EFCore.Design/Properties/DesignStrings.resx
@@ -157,7 +157,7 @@
A compilation must be loaded.
- Backing field for property '{entityType}.{propertyName}' could not be inferred. Use a matching field name or configure with HasField().
+ Backing field for property '{entityType}.{propertyName}' could not be inferred. Use a matching field name or configure with 'HasField()'.
The entity type '{entityType}' has a custom constructor binding. Compiled model can't be generated, because custom constructor bindings are not supported. Configure the custom constructor binding in '{customize}' in a partial '{className}' class instead.