Repository: dotnet/efcore
File: src/EFCore.Design/Scaffolding/Internal/CSharpRuntimeModelCodeGenerator.cs (C#)

Code before:
            case PropertyInfo propertyInfo:
            {
                var methodInfo = forSet ? propertyInfo.SetMethod! : propertyInfo.GetMethod!;
                if (methodInfo.IsPublic
                    || methodInfo.IsStatic
                    || (memberAccessReplacements?.ContainsKey(methodInfo)) == true)
                {
                    return null;
                }

                member = methodInfo;

                break;
            }
        }

        memberAccessReplacements ??= [];

        var methodName = LinqToCSharpSyntaxTranslator.GetUnsafeAccessorName(member);

        var declaringType = member.DeclaringType!;
        if (declaringType.IsGenericType
            && !declaringType.IsGenericTypeDefinition)
        {
            var genericArguments = string.Join(", ", declaringType.GetGenericArguments().Select(a => _code.Reference(a)));
            declaringType = declaringType.GetGenericTypeDefinition();

            if (!unsafeAccessorClassNames.TryGetValue(declaringType, out var className))
            {
                className = Uniquifier.Uniquify(
                    declaringType.Name[..declaringType.Name.IndexOf('`')], unsafeAccessorClassNames.Inverse, int.MaxValue,
                    UnsafeAccessorsSuffix);
                unsafeAccessorClassNames[declaringType] = className;
            }

            var qualifiedName = new QualifiedName($"{className}<{genericArguments}>.{methodName}", @namespace);
            memberAccessReplacements.Add(member, qualifiedName);
            member = declaringType.GetMemberWithSameMetadataDefinitionAs(member);
        }
        else
        {
            if (!unsafeAccessorClassNames.TryGetValue(declaringType, out var className))
            {
                className = Uniquifier.Uniquify(
                    declaringType.Name, unsafeAccessorClassNames.Inverse, int.MaxValue, UnsafeAccessorsSuffix);
                unsafeAccessorClassNames[declaringType] = className;
            }

            var qualifiedName = new QualifiedName(className + "." + methodName, @namespace);
            memberAccessReplacements.Add(member, qualifiedName);
        }

Review comment (bug):
The PR title/description mentions adding handling/messages for cases where an unsafe accessor cannot be generated (e.g. `CompiledModelUnsafeAccessorNull`), but this change set only adds `CompiledModelBackingFieldNotFound` and doesn’t introduce any `CompiledModelUnsafeAccessorNull` resource or corresponding checks in the code generator. If unsafe-accessor generation failures are still possible, the PR may be missing the intended additional handling/tests.

Code after:
                {
                    return null;
                }

                break;
            }
            case PropertyInfo propertyInfo:
            {
                var methodInfo = forSet ? propertyInfo.SetMethod! : propertyInfo.GetMethod!;
                if (methodInfo.IsPublic
                    || methodInfo.IsStatic
                    || (memberAccessReplacements?.ContainsKey(methodInfo)) == true)
                {
                    return null;
                }

                member = methodInfo;

                break;
            }
        }

        memberAccessReplacements ??= [];

        var methodName = LinqToCSharpSyntaxTranslator.GetUnsafeAccessorName(member);

        var declaringType = member.DeclaringType!;
        if (declaringType.IsGenericType
            && !declaringType.IsGenericTypeDefinition)
        {
            var genericArguments = string.Join(", ", declaringType.GetGenericArguments().Select(a => _code.Reference(a)));
            declaringType = declaringType.GetGenericTypeDefinition();

            if (!unsafeAccessorClassNames.TryGetValue(declaringType, out var className))
            {
                className = Uniquifier.Uniquify(
                    declaringType.Name[..declaringType.Name.IndexOf('`')], unsafeAccessorClassNames.Inverse, int.MaxValue,
                    UnsafeAccessorsSuffix);
                unsafeAccessorClassNames[declaringType] = className;
            }

            var qualifiedName = new QualifiedName($"{className}<{genericArguments}>.{methodName}", @namespace);
            memberAccessReplacements.Add(member, qualifiedName);
            member = declaringType.GetMemberWithSameMetadataDefinitionAs(member);
        }
        else
        {
            if (!unsafeAccessorClassNames.TryGetValue(declaringType, out var className))
            {
                className = Uniquifier.Uniquify(
                    declaringType.Name, unsafeAccessorClassNames.Inverse, int.MaxValue, UnsafeAccessorsSuffix);