Skip to content

Commit 30eb1fb

Browse files
authored
Use InvariantCulture for ChangeType() and decimal.TryParse() (#35675)
fixes #35654
1 parent 5d879e3 commit 30eb1fb

File tree

4 files changed

+122
-5
lines changed

4 files changed

+122
-5
lines changed

Diff for: src/EFCore.SqlServer/Scaffolding/Internal/SqlServerDatabaseModelFactory.cs

+1-1
Original file line numberDiff line numberDiff line change
@@ -918,7 +918,7 @@ FROM [sys].[views] v
918918
{
919919
try
920920
{
921-
return Convert.ChangeType(defaultValueSql, type);
921+
return Convert.ChangeType(defaultValueSql, type, CultureInfo.InvariantCulture);
922922
}
923923
catch
924924
{

Diff for: src/EFCore.Sqlite.Core/Scaffolding/Internal/SqliteDatabaseModelFactory.cs

+3-2
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@
22
// The .NET Foundation licenses this file to you under the MIT license.
33

44
using System.Data;
5+
using System.Globalization;
56
using System.Text;
67
using System.Text.RegularExpressions;
78
using Microsoft.Data.Sqlite;
@@ -429,7 +430,7 @@ private void ParseClrDefaults(DatabaseTable table)
429430
{
430431
try
431432
{
432-
column.DefaultValue = Convert.ChangeType(defaultValueSql, type);
433+
column.DefaultValue = Convert.ChangeType(defaultValueSql, type, CultureInfo.InvariantCulture);
433434
}
434435
catch
435436
{
@@ -471,7 +472,7 @@ private void ParseClrDefaults(DatabaseTable table)
471472
column.DefaultValue = dateTimeOffset;
472473
}
473474
else if (type == typeof(decimal)
474-
&& decimal.TryParse(defaultValueSql, out var decimalValue))
475+
&& decimal.TryParse(defaultValueSql, CultureInfo.InvariantCulture, out var decimalValue))
475476
{
476477
column.DefaultValue = decimalValue;
477478
}

Diff for: test/EFCore.SqlServer.FunctionalTests/Scaffolding/SqlServerDatabaseModelFactoryTest.cs

+61
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
// Licensed to the .NET Foundation under one or more agreements.
22
// The .NET Foundation licenses this file to you under the MIT license.
33

4+
using System.Globalization;
45
using Microsoft.EntityFrameworkCore.Metadata.Internal;
56
using Microsoft.EntityFrameworkCore.Scaffolding.Metadata;
67
using Microsoft.EntityFrameworkCore.SqlServer.Diagnostics.Internal;
@@ -3939,6 +3940,7 @@ CREATE TABLE MyTable (
39393940
B decimal DEFAULT (0.0),
39403941
C decimal DEFAULT (0),
39413942
D decimal DEFAULT ((CONVERT ( ""decimal"", ( (1.1234) ) ))),
3943+
E decimal DEFAULT ((10.0)),
39423944
);",
39433945
Enumerable.Empty<string>(),
39443946
Enumerable.Empty<string>(),
@@ -3962,11 +3964,70 @@ D decimal DEFAULT ((CONVERT ( ""decimal"", ( (1.1234) ) ))),
39623964
Assert.Equal("(CONVERT([decimal],(1.1234)))", column.DefaultValueSql);
39633965
Assert.Equal((decimal)1.1234, column.DefaultValue);
39643966

3967+
column = columns.Single(c => c.Name == "E");
3968+
Assert.Equal("((10.0))", column.DefaultValueSql);
3969+
Assert.Equal((decimal)10, column.DefaultValue);
3970+
39653971
var model = scaffoldingFactory.Create(dbModel, new ModelReverseEngineerOptions());
39663972
Assert.Equal(1, model.GetEntityTypes().Count());
39673973
},
39683974
"DROP TABLE MyTable;");
39693975

3976+
[ConditionalFact]
3977+
public void Simple_decimal_literals_are_parsed_for_HasDefaultValue_with_Danish_locale()
3978+
{
3979+
var currentCulture = CultureInfo.CurrentCulture;
3980+
3981+
try
3982+
{
3983+
CultureInfo.CurrentCulture = new CultureInfo("da-DK");
3984+
Test(
3985+
@"
3986+
CREATE TABLE MyTable (
3987+
Id int,
3988+
A decimal DEFAULT -1.1111,
3989+
B decimal DEFAULT (0.0),
3990+
C decimal DEFAULT (0),
3991+
D decimal DEFAULT ((CONVERT ( ""decimal"", ( (1.1234) ) ))),
3992+
E decimal DEFAULT ((10.0)),
3993+
);",
3994+
Enumerable.Empty<string>(),
3995+
Enumerable.Empty<string>(),
3996+
(dbModel, scaffoldingFactory) =>
3997+
{
3998+
var columns = dbModel.Tables.Single().Columns;
3999+
4000+
var column = columns.Single(c => c.Name == "A");
4001+
Assert.Equal("((-1.1111))", column.DefaultValueSql);
4002+
Assert.Equal((decimal)-1.1111, column.DefaultValue);
4003+
4004+
column = columns.Single(c => c.Name == "B");
4005+
Assert.Equal("((0.0))", column.DefaultValueSql);
4006+
Assert.Equal((decimal)0, column.DefaultValue);
4007+
4008+
column = columns.Single(c => c.Name == "C");
4009+
Assert.Equal("((0))", column.DefaultValueSql);
4010+
Assert.Equal((decimal)0, column.DefaultValue);
4011+
4012+
column = columns.Single(c => c.Name == "D");
4013+
Assert.Equal("(CONVERT([decimal],(1.1234)))", column.DefaultValueSql);
4014+
Assert.Equal((decimal)1.1234, column.DefaultValue);
4015+
4016+
column = columns.Single(c => c.Name == "E");
4017+
Assert.Equal("((10.0))", column.DefaultValueSql);
4018+
Assert.Equal((decimal)10, column.DefaultValue);
4019+
4020+
var model = scaffoldingFactory.Create(dbModel, new ModelReverseEngineerOptions());
4021+
Assert.Equal(1, model.GetEntityTypes().Count());
4022+
},
4023+
"DROP TABLE MyTable;");
4024+
}
4025+
finally
4026+
{
4027+
CultureInfo.CurrentCulture = currentCulture;
4028+
}
4029+
}
4030+
39704031
[ConditionalFact]
39714032
public void Simple_bool_literals_are_parsed_for_HasDefaultValue()
39724033
=> Test(

Diff for: test/EFCore.Sqlite.FunctionalTests/Scaffolding/SqliteDatabaseModelFactoryTest.cs

+57-2
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
// Licensed to the .NET Foundation under one or more agreements.
22
// The .NET Foundation licenses this file to you under the MIT license.
33

4+
using System.Globalization;
45
using Microsoft.EntityFrameworkCore.Diagnostics.Internal;
56
using Microsoft.EntityFrameworkCore.Metadata.Internal;
67
using Microsoft.EntityFrameworkCore.Scaffolding.Metadata;
@@ -850,9 +851,10 @@ CREATE TABLE MyTable (
850851
Id int,
851852
A decimal DEFAULT '-1.1111',
852853
B decimal DEFAULT ('0.0'),
853-
C decimal DEFAULT ('0'));
854+
C decimal DEFAULT ('0'),
855+
D decimal DEFAULT ('10.0'));
854856
855-
INSERT INTO MyTable VALUES (1, '1.1', '1.2', '1.3');",
857+
INSERT INTO MyTable VALUES (1, '1.1', '1.2', '1.3', '1.4');",
856858
Enumerable.Empty<string>(),
857859
Enumerable.Empty<string>(),
858860
dbModel =>
@@ -870,9 +872,62 @@ B decimal DEFAULT ('0.0'),
870872
column = columns.Single(c => c.Name == "C");
871873
Assert.Equal("'0'", column.DefaultValueSql);
872874
Assert.Equal((decimal)0, column.DefaultValue);
875+
876+
column = columns.Single(c => c.Name == "D");
877+
Assert.Equal("'10.0'", column.DefaultValueSql);
878+
Assert.Equal((decimal)10, column.DefaultValue);
873879
},
874880
"DROP TABLE MyTable;");
875881

882+
[ConditionalFact]
883+
public void Simple_decimal_literals_are_parsed_for_HasDefaultValue_with_Danish_locale()
884+
{
885+
var culture = CultureInfo.CurrentCulture;
886+
887+
try
888+
{
889+
CultureInfo.CurrentCulture = new CultureInfo("da-DK");
890+
891+
Test(
892+
@"
893+
CREATE TABLE MyTable (
894+
Id int,
895+
A decimal DEFAULT '-1.1111',
896+
B decimal DEFAULT ('0.0'),
897+
C decimal DEFAULT ('0'),
898+
D decimal DEFAULT ('10.0'));
899+
900+
INSERT INTO MyTable VALUES (1, '1.1', '1.2', '1.3', '1.4');",
901+
Enumerable.Empty<string>(),
902+
Enumerable.Empty<string>(),
903+
dbModel =>
904+
{
905+
var columns = dbModel.Tables.Single().Columns;
906+
907+
var column = columns.Single(c => c.Name == "A");
908+
Assert.Equal("'-1.1111'", column.DefaultValueSql);
909+
Assert.Equal((decimal)-1.1111, column.DefaultValue);
910+
911+
column = columns.Single(c => c.Name == "B");
912+
Assert.Equal("'0.0'", column.DefaultValueSql);
913+
Assert.Equal((decimal)0, column.DefaultValue);
914+
915+
column = columns.Single(c => c.Name == "C");
916+
Assert.Equal("'0'", column.DefaultValueSql);
917+
Assert.Equal((decimal)0, column.DefaultValue);
918+
919+
column = columns.Single(c => c.Name == "D");
920+
Assert.Equal("'10.0'", column.DefaultValueSql);
921+
Assert.Equal((decimal)10, column.DefaultValue);
922+
},
923+
"DROP TABLE MyTable;");
924+
}
925+
finally
926+
{
927+
CultureInfo.CurrentCulture = culture;
928+
}
929+
}
930+
876931
[ConditionalFact]
877932
public void Simple_bool_literals_are_parsed_for_HasDefaultValue()
878933
=> Test(

0 commit comments

Comments
 (0)