diff --git a/src/EFCore.Design/Migrations/Design/CSharpSnapshotGenerator.cs b/src/EFCore.Design/Migrations/Design/CSharpSnapshotGenerator.cs index 7092724682c..365a06a3f97 100644 --- a/src/EFCore.Design/Migrations/Design/CSharpSnapshotGenerator.cs +++ b/src/EFCore.Design/Migrations/Design/CSharpSnapshotGenerator.cs @@ -576,7 +576,8 @@ protected virtual void GenerateComplexProperty( { stringBuilder .AppendLine() - .Append(".IsRequired()"); + .Append(complexTypeBuilderName) + .AppendLine(".IsRequired();"); } GenerateProperties(complexTypeBuilderName, complexType.GetDeclaredProperties(), stringBuilder); diff --git a/test/EFCore.Design.Tests/Migrations/ModelSnapshotSqlServerTest.cs b/test/EFCore.Design.Tests/Migrations/ModelSnapshotSqlServerTest.cs index dc5f28bf12b..e8d7423f232 100644 --- a/test/EFCore.Design.Tests/Migrations/ModelSnapshotSqlServerTest.cs +++ b/test/EFCore.Design.Tests/Migrations/ModelSnapshotSqlServerTest.cs @@ -7,7 +7,6 @@ using Microsoft.EntityFrameworkCore.Metadata.Internal; using Microsoft.EntityFrameworkCore.Migrations.Internal; using Microsoft.EntityFrameworkCore.SqlServer.Design.Internal; -using Microsoft.EntityFrameworkCore.SqlServer.Infrastructure.Internal; using Microsoft.EntityFrameworkCore.SqlServer.Metadata.Internal; using Microsoft.EntityFrameworkCore.SqlServer.Storage.Internal; using NetTopologySuite; @@ -66,6 +65,12 @@ private class EntityWithManyProperties public MultiPolygon SpatialCMultiPolygon { get; set; } public Point SpatialCPoint { get; set; } public Polygon SpatialCPolygon { get; set; } + public int[] Int32Collection { get; set; } + public double[] DoubleCollection { get; set; } + public string[] StringCollection { get; set; } + public DateTime[] DateTimeCollection { get; set; } + public bool[] BoolCollection { get; set; } + public byte[][] BytesCollection { get; set; } } private enum Enum64 : long @@ -5452,8 +5457,11 @@ public virtual void Complex_properties_are_stored_in_snapshot() { b.ComplexProperty(eo => eo.EntityWithTwoProperties, eb => { + eb.IsRequired(); eb.Property(e => e.AlternateId).HasColumnOrder(1); - eb.ComplexProperty(e => e.EntityWithStringKey); + eb.ComplexProperty(e => e.EntityWithStringKey).IsRequired(); + eb.HasPropertyAnnotation("PropertyAnnotation", 1); + eb.HasTypeAnnotation("TypeAnnotation", 2); }); }); }, @@ -5470,6 +5478,8 @@ public virtual void Complex_properties_are_stored_in_snapshot() b.ComplexProperty>("EntityWithTwoProperties", "Microsoft.EntityFrameworkCore.Migrations.ModelSnapshotSqlServerTest+EntityWithOneProperty.EntityWithTwoProperties#EntityWithTwoProperties", b1 => { + b1.IsRequired(); + b1.Property("AlternateId") .HasColumnType("int") .HasColumnOrder(1); @@ -5479,9 +5489,15 @@ public virtual void Complex_properties_are_stored_in_snapshot() b1.ComplexProperty>("EntityWithStringKey", "Microsoft.EntityFrameworkCore.Migrations.ModelSnapshotSqlServerTest+EntityWithOneProperty.EntityWithTwoProperties#EntityWithTwoProperties.EntityWithStringKey#EntityWithStringKey", b2 => { + b2.IsRequired(); + b2.Property("Id") .HasColumnType("nvarchar(max)"); }); + + b1.HasPropertyAnnotation("PropertyAnnotation", 1); + + b1.HasTypeAnnotation("TypeAnnotation", 2); }); b.HasKey("Id"); @@ -5496,17 +5512,19 @@ public virtual void Complex_properties_are_stored_in_snapshot() var complexProperty = entityWithOneProperty.FindComplexProperty(nameof(EntityWithOneProperty.EntityWithTwoProperties)); Assert.False(complexProperty.IsCollection); - Assert.True(complexProperty.IsNullable); + Assert.False(complexProperty.IsNullable); var complexType = complexProperty.ComplexType; Assert.Equal("Microsoft.EntityFrameworkCore.Migrations.ModelSnapshotSqlServerTest+EntityWithOneProperty.EntityWithTwoProperties#EntityWithTwoProperties", complexType.Name); Assert.Equal("EntityWithOneProperty.EntityWithTwoProperties#EntityWithTwoProperties", complexType.DisplayName()); Assert.Equal(nameof(EntityWithOneProperty), complexType.GetTableName()); var alternateIdProperty = complexType.FindProperty(nameof(EntityWithTwoProperties.AlternateId)); Assert.Equal(1, alternateIdProperty.GetColumnOrder()); + Assert.Equal(1, complexProperty["PropertyAnnotation"]); + Assert.Equal(2, complexProperty.ComplexType["TypeAnnotation"]); var nestedComplexProperty = complexType.FindComplexProperty(nameof(EntityWithTwoProperties.EntityWithStringKey)); Assert.False(nestedComplexProperty.IsCollection); - Assert.True(nestedComplexProperty.IsNullable); + Assert.False(nestedComplexProperty.IsNullable); var nestedComplexType = nestedComplexProperty.ComplexType; Assert.Equal("Microsoft.EntityFrameworkCore.Migrations.ModelSnapshotSqlServerTest+EntityWithOneProperty.EntityWithTwoProperties#EntityWithTwoProperties.EntityWithStringKey#EntityWithStringKey", nestedComplexType.Name); Assert.Equal("EntityWithOneProperty.EntityWithTwoProperties#EntityWithTwoProperties.EntityWithStringKey#EntityWithStringKey", nestedComplexType.DisplayName()); @@ -7220,7 +7238,13 @@ static List getAllProperties(IModel model) SpatialCMultiPoint = multiPoint, SpatialCMultiPolygon = multiPolygon, SpatialCPoint = point1, - SpatialCPolygon = polygon1 + SpatialCPolygon = polygon1, + Int32Collection = new[] { 1, 2, 3, 4 }, + DoubleCollection = new[] { 1.2, 3.4 }, + StringCollection = new[] { "AB", "CD" }, + DateTimeCollection = new[] { new DateTime(2023, 9, 7), new DateTime(2023, 11, 14) }, + BoolCollection = new[] { true, false }, + BytesCollection = new[] { new byte[] { 1, 2 }, new byte[] { 3, 4 } } }, new { @@ -7288,6 +7312,9 @@ protected override void BuildModel(ModelBuilder modelBuilder) SqlServerPropertyBuilderExtensions.UseIdentityColumn(b.Property("Id")); + b.Property("BoolCollection") + .HasColumnType("nvarchar(max)"); + b.Property("Boolean") .HasColumnType("bit"); @@ -7297,6 +7324,9 @@ protected override void BuildModel(ModelBuilder modelBuilder) b.Property("Bytes") .HasColumnType("varbinary(max)"); + b.Property("BytesCollection") + .HasColumnType("nvarchar(max)"); + b.Property("Character") .IsRequired() .HasColumnType("nvarchar(1)"); @@ -7304,6 +7334,9 @@ protected override void BuildModel(ModelBuilder modelBuilder) b.Property("DateTime") .HasColumnType("datetime2"); + b.Property("DateTimeCollection") + .HasColumnType("nvarchar(max)"); + b.Property("DateTimeOffset") .HasColumnType("datetimeoffset"); @@ -7313,6 +7346,9 @@ protected override void BuildModel(ModelBuilder modelBuilder) b.Property("Double") .HasColumnType("float"); + b.Property("DoubleCollection") + .HasColumnType("nvarchar(max)"); + b.Property("Enum16") .HasColumnType("smallint"); @@ -7343,6 +7379,9 @@ protected override void BuildModel(ModelBuilder modelBuilder) b.Property("Int32") .HasColumnType("int"); + b.Property("Int32Collection") + .HasColumnType("nvarchar(max)"); + b.Property("Int64") .HasColumnType("bigint"); @@ -7400,6 +7439,9 @@ protected override void BuildModel(ModelBuilder modelBuilder) b.Property("String") .HasColumnType("nvarchar(max)"); + b.Property("StringCollection") + .HasColumnType("nvarchar(max)"); + b.Property("TimeSpan") .HasColumnType("time"); @@ -7420,14 +7462,18 @@ protected override void BuildModel(ModelBuilder modelBuilder) new { Id = 42, + BoolCollection = "[true,false]", Boolean = true, Byte = (byte)55, Bytes = new byte[] { 44, 45 }, + BytesCollection = "[\"AQI=\",\"AwQ=\"]", Character = "9", DateTime = new DateTime(1973, 9, 3, 12, 10, 42, 344, DateTimeKind.Utc), + DateTimeCollection = "[\"2023-09-07T00:00:00\",\"2023-11-14T00:00:00\"]", DateTimeOffset = new DateTimeOffset(new DateTime(1973, 9, 3, 12, 10, 42, 344, DateTimeKind.Unspecified), new TimeSpan(0, 1, 0, 0, 0)), Decimal = 50.0m, Double = 49.0, + DoubleCollection = "[1.2,3.4]", Enum16 = (short)1, Enum32 = 1, Enum64 = 1L, @@ -7438,6 +7484,7 @@ protected override void BuildModel(ModelBuilder modelBuilder) EnumU64 = 1234567890123456789m, Int16 = (short)46, Int32 = 47, + Int32Collection = "[1,2,3,4]", Int64 = 48L, SignedByte = (short)60, Single = 54f, @@ -7456,6 +7503,7 @@ protected override void BuildModel(ModelBuilder modelBuilder) SpatialCPoint = (NetTopologySuite.Geometries.Point)new NetTopologySuite.IO.WKTReader().Read("SRID=4326;POINT Z(1.1 2.2 3.3)"), SpatialCPolygon = (NetTopologySuite.Geometries.Polygon)new NetTopologySuite.IO.WKTReader().Read("SRID=4326;POLYGON ((1.1 2.2, 2.2 2.2, 2.2 1.1, 1.1 2.2))"), String = "FortyThree", + StringCollection = "[\"AB\",\"CD\"]", TimeSpan = new TimeSpan(2, 3, 52, 53, 0), UnsignedInt16 = 56, UnsignedInt32 = 57L, @@ -7583,6 +7631,13 @@ protected override void BuildModel(ModelBuilder modelBuilder) Assert.Equal(4326, ((Geometry)seed["SpatialCMultiPolygon"]).SRID); Assert.Equal(4326, ((Geometry)seed["SpatialCPoint"]).SRID); Assert.Equal(4326, ((Geometry)seed["SpatialCPolygon"]).SRID); + + Assert.Equal("[1,2,3,4]", seed["Int32Collection"]); + Assert.Equal("[1.2,3.4]", seed["DoubleCollection"]); + Assert.Equal("[\"AB\",\"CD\"]", seed["StringCollection"]); + Assert.Equal("[\"2023-09-07T00:00:00\",\"2023-11-14T00:00:00\"]", seed["DateTimeCollection"]); + Assert.Equal("[true,false]", seed["BoolCollection"]); + Assert.Equal("[\"AQI=\",\"AwQ=\"]", seed["BytesCollection"]); }, seed => {