diff --git a/src/EFCore.Relational/Extensions/RelationalPropertyExtensions.cs b/src/EFCore.Relational/Extensions/RelationalPropertyExtensions.cs index 3ae8d586c88..e7ac71135f9 100644 --- a/src/EFCore.Relational/Extensions/RelationalPropertyExtensions.cs +++ b/src/EFCore.Relational/Extensions/RelationalPropertyExtensions.cs @@ -1250,9 +1250,7 @@ public static void SetComment(this IMutableProperty property, string? comment) /// The property. /// The collation for the column this property is mapped to. public static string? GetCollation(this IReadOnlyProperty property) - => (property is RuntimeProperty) - ? throw new InvalidOperationException(CoreStrings.RuntimeModelMissingData) - : (string?)property.FindAnnotation(RelationalAnnotationNames.Collation)?.Value; + => (string?)property.FindAnnotation(RelationalAnnotationNames.Collation)?.Value; /// /// Returns the collation to be used for the column. @@ -1262,11 +1260,6 @@ public static void SetComment(this IMutableProperty property, string? comment) /// The collation for the column this property is mapped to. public static string? GetCollation(this IReadOnlyProperty property, in StoreObjectIdentifier storeObject) { - if (property is RuntimeProperty) - { - throw new InvalidOperationException(CoreStrings.RuntimeModelMissingData); - } - var annotation = property.FindAnnotation(RelationalAnnotationNames.Collation); return annotation != null ? (string?)annotation.Value diff --git a/src/EFCore.SqlServer/Design/Internal/SqlServerCSharpRuntimeAnnotationCodeGenerator.cs b/src/EFCore.SqlServer/Design/Internal/SqlServerCSharpRuntimeAnnotationCodeGenerator.cs index 5a5466ced33..ecbe55311b0 100644 --- a/src/EFCore.SqlServer/Design/Internal/SqlServerCSharpRuntimeAnnotationCodeGenerator.cs +++ b/src/EFCore.SqlServer/Design/Internal/SqlServerCSharpRuntimeAnnotationCodeGenerator.cs @@ -58,6 +58,11 @@ public override void Generate(IProperty property, CSharpRuntimeAnnotationCodeGen { annotations[SqlServerAnnotationNames.ValueGenerationStrategy] = property.GetValueGenerationStrategy(); } + + if (!annotations.ContainsKey(RelationalAnnotationNames.Collation)) + { + annotations[RelationalAnnotationNames.Collation] = property.GetCollation(); + } } base.Generate(property, parameters); diff --git a/src/EFCore.SqlServer/Metadata/Conventions/SqlServerRuntimeModelConvention.cs b/src/EFCore.SqlServer/Metadata/Conventions/SqlServerRuntimeModelConvention.cs index e9118e97711..1818de4e7d3 100644 --- a/src/EFCore.SqlServer/Metadata/Conventions/SqlServerRuntimeModelConvention.cs +++ b/src/EFCore.SqlServer/Metadata/Conventions/SqlServerRuntimeModelConvention.cs @@ -67,6 +67,11 @@ public class SqlServerRuntimeModelConvention : RelationalRuntimeModelConvention { annotations[SqlServerAnnotationNames.ValueGenerationStrategy] = property.GetValueGenerationStrategy(); } + + if (!annotations.ContainsKey(RelationalAnnotationNames.Collation)) + { + annotations[RelationalAnnotationNames.Collation] = property.GetCollation(); + } } } diff --git a/src/EFCore.SqlServer/Update/Internal/SqlServerUpdateSqlGenerator.cs b/src/EFCore.SqlServer/Update/Internal/SqlServerUpdateSqlGenerator.cs index bf6827a2482..ef69e7d663d 100644 --- a/src/EFCore.SqlServer/Update/Internal/SqlServerUpdateSqlGenerator.cs +++ b/src/EFCore.SqlServer/Update/Internal/SqlServerUpdateSqlGenerator.cs @@ -767,12 +767,15 @@ protected virtual int MergeIntoMinimumThreshold private static string GetTypeNameForCopy(IProperty property) { var typeName = property.GetColumnType(); + var collation = property[RelationalAnnotationNames.Collation]?.ToString(); - return property.ClrType == typeof(byte[]) + typeName = property.ClrType == typeof(byte[]) && (typeName.Equals("rowversion", StringComparison.OrdinalIgnoreCase) || typeName.Equals("timestamp", StringComparison.OrdinalIgnoreCase)) ? property.IsNullable ? "varbinary(8)" : "binary(8)" : typeName; + + return collation is null ? typeName : $"{typeName} COLLATE {collation}"; } /// diff --git a/test/EFCore.Design.Tests/Scaffolding/Internal/CSharpRuntimeModelCodeGeneratorTest.cs b/test/EFCore.Design.Tests/Scaffolding/Internal/CSharpRuntimeModelCodeGeneratorTest.cs index a6f25ac4bea..5dd1120df7e 100644 --- a/test/EFCore.Design.Tests/Scaffolding/Internal/CSharpRuntimeModelCodeGeneratorTest.cs +++ b/test/EFCore.Design.Tests/Scaffolding/Internal/CSharpRuntimeModelCodeGeneratorTest.cs @@ -1904,9 +1904,6 @@ public static void CreateAnnotations(RuntimeEntityType runtimeEntityType) CoreStrings.RuntimeModelMissingData, Assert.Throws(() => detailsProperty.IsSparse()).Message); Assert.Null(detailsProperty[RelationalAnnotationNames.Collation]); - Assert.Equal( - CoreStrings.RuntimeModelMissingData, - Assert.Throws(() => detailsProperty.GetCollation()).Message); var ownedFragment = referenceOwnedType.GetMappingFragments().Single(); Assert.Equal(nameof(OwnedType.Details), detailsProperty.GetColumnName(ownedFragment.StoreObject));