Repository: dotnet/efcore (2025-08-21T00:03:07Z)

Issue:
Complex collections are scaffolded with the wrong type in the snapshot
```C#
        modelBuilder.Entity<Person>(b =>
        {
            b.ComplexProperty(p => p.Details, pb =>
            {
                pb.ToJson();
            });
        });
```

```C#

public class Person
{
    public Guid Id { get; set; }
    public string Name { get; set; } = null!;
    public PersonDetails Details { get; set; }
}

public struct PersonDetails()
{
    public List<Address> Addresses { get; set; } = [];
    public List<Phone> Phones { get; set; } = [];
}

public class Address
{
    public string City { get; set; } = null!;
    public string State { get; set; } = null!;
    public string Street { get; set; } = null!;
    public string ZipCode { get; set; } = null!;
}

public class Phone
{
    public string Number { get; set; } = null!;
    public PhoneType Type { get; set; } = PhoneType.Mobile;
}

public enum PhoneType
{
    Mobile,
    Home,
    Work,
    Other
}
```

Snapshot:

```C#
protected override void BuildModel(ModelBuilder modelBuilder)
{
#pragma warning disable 612, 618
    modelBuilder
        .HasAnnotation("ProductVersion", "10.0.0-rc.1.25418.116")
        .HasAnnotation("Relational:MaxIdentifierLength", 128);

    SqlServerModelBuilderExtensions.UseIdentityColumns(modelBuilder);

    modelBuilder.Entity("Person", b =>
        {
            b.Property<Guid>("Id")
                .ValueGeneratedOnAdd()
                .HasColumnType("uniqueidentifier");

            b.Property<string>("Name")
                .IsRequired()
                .HasColumnType("nvarchar(max)");

            b.ComplexProperty(typeof(Dictionary<string, object>), "Details", "Person.Details#PersonDetails", b1 =>
                {
                    b1.IsRequired();

                    b1.ComplexCollection(typeof(Dictionary<string, object>), "Addresses", "Person.Details#PersonDetails.Addresses#Address", b2 =>
                        {
                            b2.IsRequired();

                            b2.Property<string>("City")
                                .IsRequired();

                            b2.Property<string>("State")
                                .IsRequired();

                            b2.Property<string>("Street")
                                .IsRequired();

                            b2.Property<string>("ZipCode")
                                .IsRequired();
                        });

                    b1.ComplexCollection(typeof(Dictionary<string, object>), "Phones", "Person.Details#PersonDetails.Phones#Phone", b2 =>
                        {
                            b2.IsRequired();

                            b2.Property<string>("Number")
                                .IsRequired();

                            b2.Property<int>("Type");
                        });

                    b1.ToJson("Details");
                });

            b.HasKey("Id");

            b.ToTable("Persons");
        });
#pragma warning restore 612, 618
}
```


Discussion:

Patch:
diff --git a/src/EFCore.Design/Migrations/Design/CSharpSnapshotGenerator.cs b/src/EFCore.Design/Migrations/Design/CSharpSnapshotGenerator.cs
index 9938ce572ea..04a6940a970 100644
--- a/src/EFCore.Design/Migrations/Design/CSharpSnapshotGenerator.cs
+++ b/src/EFCore.Design/Migrations/Design/CSharpSnapshotGenerator.cs
@@ -565,11 +565,17 @@ protected virtual void GenerateComplexProperty(
         var complexType = complexProperty.ComplexType;
         var complexTypeBuilderName = GenerateNestedBuilderName(builderName);
 
+        var propertyType = Code.Reference(Model.DefaultPropertyBagType);
+        if (complexProperty.IsCollection)
+        {
+            propertyType = $"List<{propertyType}>";
+        }
+
         stringBuilder
             .AppendLine()
             .Append(builderName)
             .Append(complexProperty.IsCollection ? ".ComplexCollection(" : ".ComplexProperty(")
-            .Append($"typeof({Code.Reference(Model.DefaultPropertyBagType)}), ")
+            .Append($"typeof({propertyType}), ")
             .Append($"{Code.Literal(complexProperty.Name)}, {Code.Literal(complexType.Name)}, ")
             .Append(complexTypeBuilderName)
             .AppendLine(" =>");


Test patch:
diff --git a/test/EFCore.Design.Tests/Migrations/Design/CSharpMigrationsGeneratorTest.ModelSnapshot.cs b/test/EFCore.Design.Tests/Migrations/Design/CSharpMigrationsGeneratorTest.ModelSnapshot.cs
index dc8c917d64a..53ee02df81c 100644
--- a/test/EFCore.Design.Tests/Migrations/Design/CSharpMigrationsGeneratorTest.ModelSnapshot.cs
+++ b/test/EFCore.Design.Tests/Migrations/Design/CSharpMigrationsGeneratorTest.ModelSnapshot.cs
@@ -6201,7 +6201,7 @@ public virtual void Complex_types_mapped_to_json_are_stored_in_snapshot()
                                 {
                                     b2.Property<string>("Id");
 
-                                    b2.ComplexCollection(typeof(Dictionary<string, object>), "Properties", "Microsoft.EntityFrameworkCore.Migrations.Design.CSharpMigrationsGeneratorTest+EntityWithOneProperty.EntityWithTwoProperties#EntityWithTwoProperties.EntityWithStringKey#EntityWithStringKey.Properties#EntityWithStringProperty", b3 =>
+                                    b2.ComplexCollection(typeof(List<Dictionary<string, object>>), "Properties", "Microsoft.EntityFrameworkCore.Migrations.Design.CSharpMigrationsGeneratorTest+EntityWithOneProperty.EntityWithTwoProperties#EntityWithTwoProperties.EntityWithStringKey#EntityWithStringKey.Properties#EntityWithStringProperty", b3 =>
                                         {
                                             b3.Property<int>("Id");
 
@@ -6256,6 +6256,7 @@ public virtual void Complex_types_mapped_to_json_are_stored_in_snapshot()
                     entityWithStringKeyComplexType.FindComplexProperty(nameof(EntityWithStringKey.Properties));
                 Assert.True(propertiesComplexCollection.IsCollection);
                 Assert.Equal("JsonProps", propertiesComplexCollection.GetJsonPropertyName());
+                Assert.Equal(typeof(List<Dictionary<string, object>>), propertiesComplexCollection.ClrType);
             });
 
     #endregion