diff --git a/src/EFCore.Relational/Properties/RelationalStrings.Designer.cs b/src/EFCore.Relational/Properties/RelationalStrings.Designer.cs
index 2b9713407ab..44d3a756ef5 100644
--- a/src/EFCore.Relational/Properties/RelationalStrings.Designer.cs
+++ b/src/EFCore.Relational/Properties/RelationalStrings.Designer.cs
@@ -1183,6 +1183,14 @@ public static string JsonReaderInvalidTokenType(object? tokenType)
GetString("JsonReaderInvalidTokenType", nameof(tokenType)),
tokenType);
+ ///
+ /// Type mapping type '{typeMapping}', which is being used on property '{property}' on entity type '{entityType}' in a JSON document, has not defined a JsonValueReaderWriter.
+ ///
+ public static string JsonValueReadWriterMissingOnTypeMapping(object? typeMapping, object? property, object? entityType)
+ => string.Format(
+ GetString("JsonValueReadWriterMissingOnTypeMapping", nameof(typeMapping), nameof(property), nameof(entityType)),
+ typeMapping, property, entityType);
+
///
/// Entity {entity} is required but the JSON element containing it is null.
///
diff --git a/src/EFCore.Relational/Properties/RelationalStrings.resx b/src/EFCore.Relational/Properties/RelationalStrings.resx
index f426a92d9d0..806923d113b 100644
--- a/src/EFCore.Relational/Properties/RelationalStrings.resx
+++ b/src/EFCore.Relational/Properties/RelationalStrings.resx
@@ -565,6 +565,9 @@
Invalid token type: '{tokenType}'.
+
+ Type mapping type '{typeMapping}', which is being used on property '{property}' on entity type '{entityType}' in a JSON document, has not defined a JsonValueReaderWriter.
+
Entity {entity} is required but the JSON element containing it is null.
diff --git a/src/EFCore.Relational/Query/RelationalShapedQueryCompilingExpressionVisitor.ShaperProcessingExpressionVisitor.cs b/src/EFCore.Relational/Query/RelationalShapedQueryCompilingExpressionVisitor.ShaperProcessingExpressionVisitor.cs
index 50a2ca24f90..d3ea92d5912 100644
--- a/src/EFCore.Relational/Query/RelationalShapedQueryCompilingExpressionVisitor.ShaperProcessingExpressionVisitor.cs
+++ b/src/EFCore.Relational/Query/RelationalShapedQueryCompilingExpressionVisitor.ShaperProcessingExpressionVisitor.cs
@@ -2528,8 +2528,15 @@ private Expression CreateReadJsonPropertyValueExpression(
var nullable = property.IsNullable;
var typeMapping = property.GetTypeMapping();
- var jsonReaderWriterExpression = Constant(
- property.GetJsonValueReaderWriter() ?? property.GetTypeMapping().JsonValueReaderWriter!);
+ var jsonValueReaderWriter = property.GetJsonValueReaderWriter() ?? property.GetTypeMapping().JsonValueReaderWriter;
+ if (jsonValueReaderWriter is null)
+ {
+ throw new InvalidOperationException(
+ RelationalStrings.JsonValueReadWriterMissingOnTypeMapping(
+ property.GetTypeMapping().GetType().Name, property.Name, property.DeclaringType.DisplayName()));
+ }
+
+ var jsonReaderWriterExpression = Constant(jsonValueReaderWriter);
var fromJsonMethod = jsonReaderWriterExpression.Type.GetMethod(
nameof(JsonValueReaderWriter.FromJsonTyped),
diff --git a/src/EFCore.Relational/Update/ModificationCommand.cs b/src/EFCore.Relational/Update/ModificationCommand.cs
index 9338966f332..ad8108d2091 100644
--- a/src/EFCore.Relational/Update/ModificationCommand.cs
+++ b/src/EFCore.Relational/Update/ModificationCommand.cs
@@ -873,7 +873,15 @@ private void WriteJson(
if (value is not null)
{
- (property.GetJsonValueReaderWriter() ?? property.GetTypeMapping().JsonValueReaderWriter)!.ToJson(writer, value);
+ var jsonValueReaderWriter = property.GetJsonValueReaderWriter() ?? property.GetTypeMapping().JsonValueReaderWriter;
+ if (jsonValueReaderWriter is null)
+ {
+ throw new InvalidOperationException(
+ RelationalStrings.JsonValueReadWriterMissingOnTypeMapping(
+ property.GetTypeMapping().GetType().Name, property.Name, entityType.DisplayName()));
+ }
+
+ jsonValueReaderWriter.ToJson(writer, value);
}
else
{
diff --git a/src/EFCore.SqlServer/Query/Internal/SqlServerQueryableMethodTranslatingExpressionVisitor.cs b/src/EFCore.SqlServer/Query/Internal/SqlServerQueryableMethodTranslatingExpressionVisitor.cs
index be2c39fcfe2..4cf4811e572 100644
--- a/src/EFCore.SqlServer/Query/Internal/SqlServerQueryableMethodTranslatingExpressionVisitor.cs
+++ b/src/EFCore.SqlServer/Query/Internal/SqlServerQueryableMethodTranslatingExpressionVisitor.cs
@@ -250,6 +250,7 @@ protected override ShapedQueryExpression TransformJsonQueryToTable(JsonQueryExpr
}
}
+ // Navigations represent nested JSON owned entities, which we also add to the OPENJSON WITH clause, but with AS JSON.
foreach (var navigation in GetAllNavigationsInHierarchy(jsonQueryExpression.EntityType)
.Where(
n => n.ForeignKey.IsOwnership
diff --git a/src/EFCore/ChangeTracking/Internal/InternalEntityEntry.OriginalValues.cs b/src/EFCore/ChangeTracking/Internal/InternalEntityEntry.OriginalValues.cs
index 8aad9eb21dc..1e1b15bb8de 100644
--- a/src/EFCore/ChangeTracking/Internal/InternalEntityEntry.OriginalValues.cs
+++ b/src/EFCore/ChangeTracking/Internal/InternalEntityEntry.OriginalValues.cs
@@ -17,27 +17,20 @@ public OriginalValues(InternalEntityEntry entry)
}
public object? GetValue(InternalEntityEntry entry, IProperty property)
- {
- var index = property.GetOriginalValueIndex();
- if (index == -1)
- {
- throw new InvalidOperationException(
- CoreStrings.OriginalValueNotTracked(property.Name, property.DeclaringType.DisplayName()));
- }
-
- return IsEmpty ? entry[property] : _values[index];
- }
+ => property.GetOriginalValueIndex() is var index && index == -1
+ ? throw new InvalidOperationException(
+ CoreStrings.OriginalValueNotTracked(property.Name, property.DeclaringType.DisplayName()))
+ : IsEmpty
+ ? entry[property]
+ : _values[index];
public T GetValue(InternalEntityEntry entry, IProperty property, int index)
- {
- if (index == -1)
- {
- throw new InvalidOperationException(
- CoreStrings.OriginalValueNotTracked(property.Name, property.DeclaringType.DisplayName()));
- }
-
- return IsEmpty ? entry.GetCurrentValue(property) : _values.GetValue(index);
- }
+ => index == -1
+ ? throw new InvalidOperationException(
+ CoreStrings.OriginalValueNotTracked(property.Name, property.DeclaringType.DisplayName()))
+ : IsEmpty
+ ? entry.GetCurrentValue(property)
+ : _values.GetValue(index);
public void SetValue(IProperty property, object? value, int index)
{
diff --git a/src/EFCore/ChangeTracking/Internal/InternalEntityEntry.cs b/src/EFCore/ChangeTracking/Internal/InternalEntityEntry.cs
index 846a23acc36..3e1b08c2a5d 100644
--- a/src/EFCore/ChangeTracking/Internal/InternalEntityEntry.cs
+++ b/src/EFCore/ChangeTracking/Internal/InternalEntityEntry.cs
@@ -922,8 +922,7 @@ public T ReadTemporaryValue(int storeGeneratedIndex)
=> _temporaryValues.GetValue(storeGeneratedIndex);
private static readonly MethodInfo GetCurrentValueMethod
- = typeof(InternalEntityEntry).GetTypeInfo().GetDeclaredMethods(nameof(GetCurrentValue)).Single(
- m => m.IsGenericMethod);
+ = typeof(InternalEntityEntry).GetTypeInfo().GetDeclaredMethods(nameof(GetCurrentValue)).Single(m => m.IsGenericMethod);
[UnconditionalSuppressMessage(
"ReflectionAnalysis", "IL2060",
diff --git a/src/EFCore/ChangeTracking/Internal/SnapshotFactoryFactory.cs b/src/EFCore/ChangeTracking/Internal/SnapshotFactoryFactory.cs
index aba7539759d..2ef9109cc37 100644
--- a/src/EFCore/ChangeTracking/Internal/SnapshotFactoryFactory.cs
+++ b/src/EFCore/ChangeTracking/Internal/SnapshotFactoryFactory.cs
@@ -106,29 +106,25 @@ protected virtual Expression CreateSnapshotExpression(
for (var i = 0; i < count; i++)
{
var propertyBase = propertyBases[i];
- if (propertyBase == null)
- {
- arguments[i] = Expression.Constant(null);
- types[i] = typeof(object);
- continue;
- }
-
- if (propertyBase is IProperty property)
- {
- arguments[i] = CreateSnapshotValueExpression(CreateReadValueExpression(parameter, property), property);
- continue;
- }
-
- if (propertyBase is IComplexProperty complexProperty)
- {
- arguments[i] = CreateSnapshotValueExpression(CreateReadValueExpression(parameter, complexProperty), complexProperty);
- continue;
- }
- if (propertyBase.IsShadowProperty())
+ switch (propertyBase)
{
- arguments[i] = CreateSnapshotValueExpression(CreateReadShadowValueExpression(parameter, propertyBase), propertyBase);
- continue;
+ case null:
+ arguments[i] = Expression.Constant(null);
+ types[i] = typeof(object);
+ continue;
+
+ case IProperty property:
+ arguments[i] = CreateSnapshotValueExpression(CreateReadValueExpression(parameter, property), property);
+ continue;
+
+ case IComplexProperty complexProperty:
+ arguments[i] = CreateSnapshotValueExpression(CreateReadValueExpression(parameter, complexProperty), complexProperty);
+ continue;
+
+ case var _ when propertyBase.IsShadowProperty():
+ arguments[i] = CreateSnapshotValueExpression(CreateReadShadowValueExpression(parameter, propertyBase), propertyBase);
+ continue;
}
var memberInfo = propertyBase.GetMemberInfo(forMaterialization: false, forSet: false);
diff --git a/test/EFCore.Relational.Specification.Tests/JsonTypesRelationalTestBase.cs b/test/EFCore.Relational.Specification.Tests/JsonTypesRelationalTestBase.cs
index 227948d01fd..a549180e00f 100644
--- a/test/EFCore.Relational.Specification.Tests/JsonTypesRelationalTestBase.cs
+++ b/test/EFCore.Relational.Specification.Tests/JsonTypesRelationalTestBase.cs
@@ -47,6 +47,59 @@ public virtual void Can_read_write_collection_of_ASCII_string_JSON_values(object
{ RelationalAnnotationNames.StoreType, storeType }, { CoreAnnotationNames.Unicode, false }
});
+ public override void Can_read_write_ulong_enum_JSON_values(EnumU64 value, string json)
+ {
+ // Relational databases don't support unsigned numeric types, so ulong is value-converted to long
+ if (value == EnumU64.Max)
+ {
+ json = """{"Prop":-1}""";
+ }
+
+ base.Can_read_write_ulong_enum_JSON_values(value, json);
+ }
+
+ public override void Can_read_write_nullable_ulong_enum_JSON_values(object? value, string json)
+ {
+ // Relational databases don't support unsigned numeric types, so ulong is value-converted to long
+ if (Equals(value, ulong.MaxValue))
+ {
+ json = """{"Prop":-1}""";
+ }
+
+ base.Can_read_write_nullable_ulong_enum_JSON_values(value, json);
+ }
+
+ public override void Can_read_write_collection_of_ulong_enum_JSON_values()
+ => Can_read_and_write_JSON_value>(
+ nameof(EnumU64CollectionType.EnumU64),
+ new List
+ {
+ EnumU64.Min,
+ EnumU64.Max,
+ EnumU64.Default,
+ EnumU64.One,
+ (EnumU64)8
+ },
+ // Relational databases don't support unsigned numeric types, so ulong is value-converted to long
+ """{"Prop":[0,-1,0,1,8]}""",
+ mappedCollection: true);
+
+ public override void Can_read_write_collection_of_nullable_ulong_enum_JSON_values()
+ => Can_read_and_write_JSON_value>(
+ nameof(NullableEnumU64CollectionType.EnumU64),
+ new List
+ {
+ EnumU64.Min,
+ null,
+ EnumU64.Max,
+ EnumU64.Default,
+ EnumU64.One,
+ (EnumU64?)8
+ },
+ // Relational databases don't support unsigned numeric types, so ulong is value-converted to long
+ """{"Prop":[0,null,-1,0,1,8]}""",
+ mappedCollection: true);
+
protected override void AssertElementFacets(IElementType element, Dictionary? facets)
{
base.AssertElementFacets(element, facets);
diff --git a/test/EFCore.Relational.Specification.Tests/Query/JsonQueryFixtureBase.cs b/test/EFCore.Relational.Specification.Tests/Query/JsonQueryFixtureBase.cs
index a6d6e12fd46..a78303d3971 100644
--- a/test/EFCore.Relational.Specification.Tests/Query/JsonQueryFixtureBase.cs
+++ b/test/EFCore.Relational.Specification.Tests/Query/JsonQueryFixtureBase.cs
@@ -13,14 +13,7 @@ public Func GetContextCreator()
=> () => CreateContext();
public virtual ISetSource GetExpectedData()
- {
- if (_expectedData == null)
- {
- _expectedData = new JsonQueryData();
- }
-
- return _expectedData;
- }
+ => _expectedData ??= new JsonQueryData();
public IReadOnlyDictionary EntitySorters { get; } = new Dictionary>
{
diff --git a/test/EFCore.Relational.Specification.Tests/TestUtilities/TestSqlLoggerFactory.cs b/test/EFCore.Relational.Specification.Tests/TestUtilities/TestSqlLoggerFactory.cs
index bf57b50d51e..12eb14f7557 100644
--- a/test/EFCore.Relational.Specification.Tests/TestUtilities/TestSqlLoggerFactory.cs
+++ b/test/EFCore.Relational.Specification.Tests/TestUtilities/TestSqlLoggerFactory.cs
@@ -254,7 +254,7 @@ void RewriteSourceWithNewBaseline(string fileName, int lineNumber)
indentBuilder.Append(" ");
var indent = indentBuilder.ToString();
var newBaseLine = $@"Assert{(forUpdate ? "ExecuteUpdate" : "")}Sql(
-{string.Join("," + Environment.NewLine + indent + "//" + Environment.NewLine, SqlStatements.Skip(offset).Take(count).Select(sql => "\"\"\"" + Environment.NewLine + sql + Environment.NewLine + "\"\"\""))})";
+{string.Join("," + Environment.NewLine + indent + "//" + Environment.NewLine, SqlStatements.Skip(offset).Take(count).Select(sql => indent + "\"\"\"" + Environment.NewLine + sql + Environment.NewLine + "\"\"\""))})";
var numNewlinesInRewritten = newBaseLine.Count(c => c is '\n' or '\r');
writer.Write(newBaseLine);
diff --git a/test/EFCore.Specification.Tests/Query/Ef6GroupByTestBase.cs b/test/EFCore.Specification.Tests/Query/Ef6GroupByTestBase.cs
index 1be89215b40..c67ddb8862f 100644
--- a/test/EFCore.Specification.Tests/Query/Ef6GroupByTestBase.cs
+++ b/test/EFCore.Specification.Tests/Query/Ef6GroupByTestBase.cs
@@ -808,14 +808,7 @@ protected override void Seed(ArubaContext context)
=> new ArubaData(context);
public virtual ISetSource GetExpectedData()
- {
- if (_expectedData == null)
- {
- _expectedData = new ArubaData();
- }
-
- return _expectedData;
- }
+ => _expectedData ??= new ArubaData();
public IReadOnlyDictionary EntitySorters { get; } = new Dictionary>
{
diff --git a/test/EFCore.SqlServer.FunctionalTests/JsonTypesSqlServerTestBase.cs b/test/EFCore.SqlServer.FunctionalTests/JsonTypesSqlServerTestBase.cs
index 27ef33a5951..933fb04927a 100644
--- a/test/EFCore.SqlServer.FunctionalTests/JsonTypesSqlServerTestBase.cs
+++ b/test/EFCore.SqlServer.FunctionalTests/JsonTypesSqlServerTestBase.cs
@@ -7,55 +7,6 @@ namespace Microsoft.EntityFrameworkCore;
public abstract class JsonTypesSqlServerTestBase : JsonTypesRelationalTestBase
{
- public override void Can_read_write_ulong_enum_JSON_values(EnumU64 value, string json)
- {
- if (value == EnumU64.Max)
- {
- json = """{"Prop":-1}"""; // Because ulong is converted to long on SQL Server
- }
-
- base.Can_read_write_ulong_enum_JSON_values(value, json);
- }
-
- public override void Can_read_write_nullable_ulong_enum_JSON_values(object? value, string json)
- {
- if (Equals(value, ulong.MaxValue))
- {
- json = """{"Prop":-1}"""; // Because ulong is converted to long on SQL Server
- }
-
- base.Can_read_write_nullable_ulong_enum_JSON_values(value, json);
- }
-
- public override void Can_read_write_collection_of_ulong_enum_JSON_values()
- => Can_read_and_write_JSON_value>(
- nameof(EnumU64CollectionType.EnumU64),
- new List
- {
- EnumU64.Min,
- EnumU64.Max,
- EnumU64.Default,
- EnumU64.One,
- (EnumU64)8
- },
- """{"Prop":[0,-1,0,1,8]}""", // Because ulong is converted to long on SQL Server
- mappedCollection: true);
-
- public override void Can_read_write_collection_of_nullable_ulong_enum_JSON_values()
- => Can_read_and_write_JSON_value>(
- nameof(NullableEnumU64CollectionType.EnumU64),
- new List
- {
- EnumU64.Min,
- null,
- EnumU64.Max,
- EnumU64.Default,
- EnumU64.One,
- (EnumU64?)8
- },
- """{"Prop":[0,null,-1,0,1,8]}""", // Because ulong is converted to long on SQL Server
- mappedCollection: true);
-
public override void Can_read_write_collection_of_fixed_length_string_JSON_values(object? storeType)
=> base.Can_read_write_collection_of_fixed_length_string_JSON_values("nchar(32)");
diff --git a/test/EFCore.SqlServer.FunctionalTests/Query/JsonQueryAdHocSqlServerTest.cs b/test/EFCore.SqlServer.FunctionalTests/Query/JsonQueryAdHocSqlServerTest.cs
index 5608c26e7ff..d34cc8fff18 100644
--- a/test/EFCore.SqlServer.FunctionalTests/Query/JsonQueryAdHocSqlServerTest.cs
+++ b/test/EFCore.SqlServer.FunctionalTests/Query/JsonQueryAdHocSqlServerTest.cs
@@ -37,39 +37,49 @@ protected override void Seed29219(MyContext29219 ctx)
ctx.SaveChanges();
ctx.Database.ExecuteSqlRaw(
- @"INSERT INTO [Entities] ([Id], [Reference], [Collection])
-VALUES(3, N'{{ ""NonNullableScalar"" : 30 }}', N'[{{ ""NonNullableScalar"" : 10001 }}]')");
+ """
+INSERT INTO [Entities] ([Id], [Reference], [Collection])
+VALUES(3, N'{{ "NonNullableScalar" : 30 }}', N'[{{ "NonNullableScalar" : 10001 }}]')
+""");
}
protected override void Seed30028(MyContext30028 ctx)
{
// complete
ctx.Database.ExecuteSqlRaw(
- @"INSERT INTO [Entities] ([Id], [Json])
+ """
+INSERT INTO [Entities] ([Id], [Json])
VALUES(
1,
-N'{{""RootName"":""e1"",""Collection"":[{{""BranchName"":""e1 c1"",""Nested"":{{""LeafName"":""e1 c1 l""}}}},{{""BranchName"":""e1 c2"",""Nested"":{{""LeafName"":""e1 c2 l""}}}}],""OptionalReference"":{{""BranchName"":""e1 or"",""Nested"":{{""LeafName"":""e1 or l""}}}},""RequiredReference"":{{""BranchName"":""e1 rr"",""Nested"":{{""LeafName"":""e1 rr l""}}}}}}')");
+N'{{"RootName":"e1","Collection":[{{"BranchName":"e1 c1","Nested":{{"LeafName":"e1 c1 l"}}}},{{"BranchName":"e1 c2","Nested":{{"LeafName":"e1 c2 l"}}}}],"OptionalReference":{{"BranchName":"e1 or","Nested":{{"LeafName":"e1 or l"}}}},"RequiredReference":{{"BranchName":"e1 rr","Nested":{{"LeafName":"e1 rr l"}}}}}}')
+""");
// missing collection
ctx.Database.ExecuteSqlRaw(
- @"INSERT INTO [Entities] ([Id], [Json])
+ """
+INSERT INTO [Entities] ([Id], [Json])
VALUES(
2,
-N'{{""RootName"":""e2"",""OptionalReference"":{{""BranchName"":""e2 or"",""Nested"":{{""LeafName"":""e2 or l""}}}},""RequiredReference"":{{""BranchName"":""e2 rr"",""Nested"":{{""LeafName"":""e2 rr l""}}}}}}')");
+N'{{"RootName":"e2","OptionalReference":{{"BranchName":"e2 or","Nested":{{"LeafName":"e2 or l"}}}},"RequiredReference":{{"BranchName":"e2 rr","Nested":{{"LeafName":"e2 rr l"}}}}}}')
+""");
// missing optional reference
ctx.Database.ExecuteSqlRaw(
- @"INSERT INTO [Entities] ([Id], [Json])
+ """
+INSERT INTO [Entities] ([Id], [Json])
VALUES(
3,
-N'{{""RootName"":""e3"",""Collection"":[{{""BranchName"":""e3 c1"",""Nested"":{{""LeafName"":""e3 c1 l""}}}},{{""BranchName"":""e3 c2"",""Nested"":{{""LeafName"":""e3 c2 l""}}}}],""RequiredReference"":{{""BranchName"":""e3 rr"",""Nested"":{{""LeafName"":""e3 rr l""}}}}}}')");
+N'{{"RootName":"e3","Collection":[{{"BranchName":"e3 c1","Nested":{{"LeafName":"e3 c1 l"}}}},{{"BranchName":"e3 c2","Nested":{{"LeafName":"e3 c2 l"}}}}],"RequiredReference":{{"BranchName":"e3 rr","Nested":{{"LeafName":"e3 rr l"}}}}}}')
+""");
// missing required reference
ctx.Database.ExecuteSqlRaw(
- @"INSERT INTO [Entities] ([Id], [Json])
+ """
+INSERT INTO [Entities] ([Id], [Json])
VALUES(
4,
-N'{{""RootName"":""e4"",""Collection"":[{{""BranchName"":""e4 c1"",""Nested"":{{""LeafName"":""e4 c1 l""}}}},{{""BranchName"":""e4 c2"",""Nested"":{{""LeafName"":""e4 c2 l""}}}}],""OptionalReference"":{{""BranchName"":""e4 or"",""Nested"":{{""LeafName"":""e4 or l""}}}}}}')");
+N'{{"RootName":"e4","Collection":[{{"BranchName":"e4 c1","Nested":{{"LeafName":"e4 c1 l"}}}},{{"BranchName":"e4 c2","Nested":{{"LeafName":"e4 c2 l"}}}}],"OptionalReference":{{"BranchName":"e4 or","Nested":{{"LeafName":"e4 or l"}}}}}}')
+""");
}
protected override void SeedArrayOfPrimitives(MyContextArrayOfPrimitives ctx)
@@ -120,24 +130,28 @@ protected override void SeedArrayOfPrimitives(MyContextArrayOfPrimitives ctx)
protected override void SeedJunkInJson(MyContextJunkInJson ctx)
=> ctx.Database.ExecuteSqlRaw(
- @"INSERT INTO [Entities] ([Collection], [CollectionWithCtor], [Reference], [ReferenceWithCtor], [Id])
+ """
+INSERT INTO [Entities] ([Collection], [CollectionWithCtor], [Reference], [ReferenceWithCtor], [Id])
VALUES(
-N'[{{""JunkReference"":{{""Something"":""SomeValue"" }},""Name"":""c11"",""JunkProperty1"":50,""Number"":11.5,""JunkCollection1"":[],""JunkCollection2"":[{{""Foo"":""junk value""}}],""NestedCollection"":[{{""DoB"":""2002-04-01T00:00:00"",""DummyProp"":""Dummy value""}},{{""DoB"":""2002-04-02T00:00:00"",""DummyReference"":{{""Foo"":5}}}}],""NestedReference"":{{""DoB"":""2002-03-01T00:00:00""}}}},{{""Name"":""c12"",""Number"":12.5,""NestedCollection"":[{{""DoB"":""2002-06-01T00:00:00""}},{{""DoB"":""2002-06-02T00:00:00""}}],""NestedDummy"":59,""NestedReference"":{{""DoB"":""2002-05-01T00:00:00""}}}}]',
-N'[{{""MyBool"":true,""Name"":""c11 ctor"",""JunkReference"":{{""Something"":""SomeValue"",""JunkCollection"":[{{""Foo"":""junk value""}}]}},""NestedCollection"":[{{""DoB"":""2002-08-01T00:00:00""}},{{""DoB"":""2002-08-02T00:00:00""}}],""NestedReference"":{{""DoB"":""2002-07-01T00:00:00""}}}},{{""MyBool"":false,""Name"":""c12 ctor"",""NestedCollection"":[{{""DoB"":""2002-10-01T00:00:00""}},{{""DoB"":""2002-10-02T00:00:00""}}],""JunkCollection"":[{{""Foo"":""junk value""}}],""NestedReference"":{{""DoB"":""2002-09-01T00:00:00""}}}}]',
-N'{{""Name"":""r1"",""JunkCollection"":[{{""Foo"":""junk value""}}],""JunkReference"":{{""Something"":""SomeValue"" }},""Number"":1.5,""NestedCollection"":[{{""DoB"":""2000-02-01T00:00:00"",""JunkReference"":{{""Something"":""SomeValue""}}}},{{""DoB"":""2000-02-02T00:00:00""}}],""NestedReference"":{{""DoB"":""2000-01-01T00:00:00""}}}}',
-N'{{""MyBool"":true,""JunkCollection"":[{{""Foo"":""junk value""}}],""Name"":""r1 ctor"",""JunkReference"":{{""Something"":""SomeValue"" }},""NestedCollection"":[{{""DoB"":""2001-02-01T00:00:00""}},{{""DoB"":""2001-02-02T00:00:00""}}],""NestedReference"":{{""JunkCollection"":[{{""Foo"":""junk value""}}],""DoB"":""2001-01-01T00:00:00""}}}}',
-1)");
+N'[{{"JunkReference":{{"Something":"SomeValue" }},"Name":"c11","JunkProperty1":50,"Number":11.5,"JunkCollection1":[],"JunkCollection2":[{{"Foo":"junk value"}}],"NestedCollection":[{{"DoB":"2002-04-01T00:00:00","DummyProp":"Dummy value"}},{{"DoB":"2002-04-02T00:00:00","DummyReference":{{"Foo":5}}}}],"NestedReference":{{"DoB":"2002-03-01T00:00:00"}}}},{{"Name":"c12","Number":12.5,"NestedCollection":[{{"DoB":"2002-06-01T00:00:00"}},{{"DoB":"2002-06-02T00:00:00"}}],"NestedDummy":59,"NestedReference":{{"DoB":"2002-05-01T00:00:00"}}}}]',
+N'[{{"MyBool":true,"Name":"c11 ctor","JunkReference":{{"Something":"SomeValue","JunkCollection":[{{"Foo":"junk value"}}]}},"NestedCollection":[{{"DoB":"2002-08-01T00:00:00"}},{{"DoB":"2002-08-02T00:00:00"}}],"NestedReference":{{"DoB":"2002-07-01T00:00:00"}}}},{{"MyBool":false,"Name":"c12 ctor","NestedCollection":[{{"DoB":"2002-10-01T00:00:00"}},{{"DoB":"2002-10-02T00:00:00"}}],"JunkCollection":[{{"Foo":"junk value"}}],"NestedReference":{{"DoB":"2002-09-01T00:00:00"}}}}]',
+N'{{"Name":"r1","JunkCollection":[{{"Foo":"junk value"}}],"JunkReference":{{"Something":"SomeValue" }},"Number":1.5,"NestedCollection":[{{"DoB":"2000-02-01T00:00:00","JunkReference":{{"Something":"SomeValue"}}}},{{"DoB":"2000-02-02T00:00:00"}}],"NestedReference":{{"DoB":"2000-01-01T00:00:00"}}}}',
+N'{{"MyBool":true,"JunkCollection":[{{"Foo":"junk value"}}],"Name":"r1 ctor","JunkReference":{{"Something":"SomeValue" }},"NestedCollection":[{{"DoB":"2001-02-01T00:00:00"}},{{"DoB":"2001-02-02T00:00:00"}}],"NestedReference":{{"JunkCollection":[{{"Foo":"junk value"}}],"DoB":"2001-01-01T00:00:00"}}}}',
+1)
+""");
protected override void SeedShadowProperties(MyContextShadowProperties ctx)
=> ctx.Database.ExecuteSqlRaw(
- @"INSERT INTO [Entities] ([Collection], [CollectionWithCtor], [Reference], [ReferenceWithCtor], [Id], [Name])
+ """
+INSERT INTO [Entities] ([Collection], [CollectionWithCtor], [Reference], [ReferenceWithCtor], [Id], [Name])
VALUES(
-N'[{{""Name"":""e1_c1"",""ShadowDouble"":5.5}},{{""ShadowDouble"":20.5,""Name"":""e1_c2""}}]',
-N'[{{""Name"":""e1_c1 ctor"",""ShadowNullableByte"":6}},{{""ShadowNullableByte"":null,""Name"":""e1_c2 ctor""}}]',
-N'{{""Name"":""e1_r"", ""ShadowString"":""Foo""}}',
-N'{{""ShadowInt"":143,""Name"":""e1_r ctor""}}',
+N'[{{"Name":"e1_c1","ShadowDouble":5.5}},{{"ShadowDouble":20.5,"Name":"e1_c2"}}]',
+N'[{{"Name":"e1_c1 ctor","ShadowNullableByte":6}},{{"ShadowNullableByte":null,"Name":"e1_c2 ctor"}}]',
+N'{{"Name":"e1_r", "ShadowString":"Foo"}}',
+N'{{"ShadowInt":143,"Name":"e1_r ctor"}}',
1,
-N'e1')");
+N'e1')
+""");
#region EnumLegacyValues
@@ -254,12 +268,14 @@ public virtual async Task Read_json_entity_collection_with_enum_properties_with_
private void SeedEnumLegacyValues(MyContextEnumLegacyValues ctx)
=> ctx.Database.ExecuteSqlRaw(
- @"INSERT INTO [Entities] ([Collection], [Reference], [Id], [Name])
+ """
+INSERT INTO [Entities] ([Collection], [Reference], [Id], [Name])
VALUES(
-N'[{{""ByteEnum"":""Bellevue"",""IntEnum"":""Foo"",""LongEnum"":""One"",""ULongEnum"":""One"",""Name"":""e1_c1"",""NullableEnum"":""Bar""}},{{""ByteEnum"":""Seattle"",""IntEnum"":""Baz"",""LongEnum"":""Two"",""ULongEnum"":""Two"",""Name"":""e1_c2"",""NullableEnum"":null}}]',
-N'{{""ByteEnum"":""Redmond"",""IntEnum"":""Foo"",""LongEnum"":""Three"",""ULongEnum"":""Three"",""Name"":""e1_r"",""NullableEnum"":""Bar""}}',
+N'[{{"ByteEnum":"Bellevue","IntEnum":"Foo","LongEnum":"One","ULongEnum":"One","Name":"e1_c1","NullableEnum":"Bar"}},{{"ByteEnum":"Seattle","IntEnum":"Baz","LongEnum":"Two","ULongEnum":"Two","Name":"e1_c2","NullableEnum":null}}]',
+N'{{"ByteEnum":"Redmond","IntEnum":"Foo","LongEnum":"Three","ULongEnum":"Three","Name":"e1_r","NullableEnum":"Bar"}}',
1,
-N'e1')");
+N'e1')
+""");
private class MyContextEnumLegacyValues : DbContext
{