diff --git a/src/EFCore.Relational/Metadata/Conventions/RelationalMapToJsonConvention.cs b/src/EFCore.Relational/Metadata/Conventions/RelationalMapToJsonConvention.cs index a699f3d4fce..7ba1c5ed663 100644 --- a/src/EFCore.Relational/Metadata/Conventions/RelationalMapToJsonConvention.cs +++ b/src/EFCore.Relational/Metadata/Conventions/RelationalMapToJsonConvention.cs @@ -70,7 +70,7 @@ public virtual void ProcessModelFinalizing( { foreach (var jsonEntityType in modelBuilder.Metadata.GetEntityTypes().Where(e => e.IsMappedToJson())) { - foreach (var enumProperty in jsonEntityType.GetDeclaredProperties().Where(p => p.ClrType.IsEnum)) + foreach (var enumProperty in jsonEntityType.GetDeclaredProperties().Where(p => p.ClrType.UnwrapNullableType().IsEnum)) { // by default store enums as strings - values should be human-readable enumProperty.Builder.HasConversion(typeof(string)); diff --git a/src/EFCore.Relational/Query/RelationalShapedQueryCompilingExpressionVisitor.ShaperProcessingExpressionVisitor.ClientMethods.cs b/src/EFCore.Relational/Query/RelationalShapedQueryCompilingExpressionVisitor.ShaperProcessingExpressionVisitor.ClientMethods.cs index 5e0481f0887..a0bbb7a0aed 100644 --- a/src/EFCore.Relational/Query/RelationalShapedQueryCompilingExpressionVisitor.ShaperProcessingExpressionVisitor.ClientMethods.cs +++ b/src/EFCore.Relational/Query/RelationalShapedQueryCompilingExpressionVisitor.ShaperProcessingExpressionVisitor.ClientMethods.cs @@ -125,12 +125,19 @@ private static TValue ThrowExtractJsonPropertyException( exception); } - private static object? ExtractJsonProperty(JsonElement element, string propertyName, Type returnType) - { - var jsonElementProperty = element.GetProperty(propertyName); - - return jsonElementProperty.Deserialize(returnType); - } + private static T? ExtractJsonProperty(JsonElement element, string propertyName, bool nullable) + => nullable + ? element.TryGetProperty(propertyName, out var jsonValue) + ? jsonValue.Deserialize() + : default + : element.GetProperty(propertyName).Deserialize(); + + //private static object? ExtractJsonProperty(JsonElement element, string propertyName, Type returnType) + //{ + // var jsonElementProperty = element.GetProperty(propertyName); + + // return jsonElementProperty.Deserialize(returnType); + //} private static void IncludeReference( QueryContext queryContext, diff --git a/src/EFCore.Relational/Query/RelationalShapedQueryCompilingExpressionVisitor.ShaperProcessingExpressionVisitor.cs b/src/EFCore.Relational/Query/RelationalShapedQueryCompilingExpressionVisitor.ShaperProcessingExpressionVisitor.cs index 88427197c58..c15bf8da1ed 100644 --- a/src/EFCore.Relational/Query/RelationalShapedQueryCompilingExpressionVisitor.ShaperProcessingExpressionVisitor.cs +++ b/src/EFCore.Relational/Query/RelationalShapedQueryCompilingExpressionVisitor.ShaperProcessingExpressionVisitor.cs @@ -1501,34 +1501,79 @@ private Expression CreateExtractJsonPropertyExpression( ParameterExpression jsonElementParameter, IProperty property) { + var nullable = property.IsNullable; Expression resultExpression; if (property.GetTypeMapping().Converter is ValueConverter converter) { - resultExpression = Expression.Call( - ExtractJsonPropertyMethodInfo, - jsonElementParameter, - Expression.Constant(property.GetJsonPropertyName()), - Expression.Constant(converter.ProviderClrType)); - - if (resultExpression.Type != converter.ProviderClrType) + var providerClrType = converter.ProviderClrType.MakeNullable(nullable); + if (!property.IsNullable || converter.ConvertsNulls) { - resultExpression = Expression.Convert(resultExpression, converter.ProviderClrType); + resultExpression = Expression.Call( + ExtractJsonPropertyMethodInfo.MakeGenericMethod(providerClrType), + jsonElementParameter, + Expression.Constant(property.GetJsonPropertyName()), + Expression.Constant(nullable)); + + resultExpression = ReplacingExpressionVisitor.Replace( + converter.ConvertFromProviderExpression.Parameters.Single(), + resultExpression, + converter.ConvertFromProviderExpression.Body); + + if (resultExpression.Type != property.ClrType) + { + resultExpression = Expression.Convert(resultExpression, property.ClrType); + } } + else + { + // property is nullable and the converter can't handle nulls + // we need to peek into the JSON value and only pass it thru converter if it's not null + var jsonPropertyCall = Expression.Call( + ExtractJsonPropertyMethodInfo.MakeGenericMethod(providerClrType), + jsonElementParameter, + Expression.Constant(property.GetJsonPropertyName()), + Expression.Constant(nullable)); - resultExpression = ReplacingExpressionVisitor.Replace( - converter.ConvertFromProviderExpression.Parameters.Single(), - resultExpression, - converter.ConvertFromProviderExpression.Body); + var jsonPropertyVariable = Expression.Variable(providerClrType); + var jsonPropertyAssignment = Expression.Assign(jsonPropertyVariable, jsonPropertyCall); + + var testExpression = Expression.NotEqual( + jsonPropertyVariable, + Expression.Default(providerClrType)); + + var ifTrueExpression = (Expression)jsonPropertyVariable; + if (ifTrueExpression.Type != converter.ProviderClrType) + { + ifTrueExpression = Expression.Convert(ifTrueExpression, converter.ProviderClrType); + } + + ifTrueExpression = ReplacingExpressionVisitor.Replace( + converter.ConvertFromProviderExpression.Parameters.Single(), + ifTrueExpression, + converter.ConvertFromProviderExpression.Body); + + if (ifTrueExpression.Type != property.ClrType) + { + ifTrueExpression = Expression.Convert(ifTrueExpression, property.ClrType); + } + + var condition = Expression.Condition( + testExpression, + ifTrueExpression, + Expression.Default(property.ClrType)); + + resultExpression = Expression.Block( + new ParameterExpression[] { jsonPropertyVariable }, + new Expression[] { jsonPropertyAssignment, condition }); + } } else { - resultExpression = Expression.Convert( - Expression.Call( - ExtractJsonPropertyMethodInfo, - jsonElementParameter, - Expression.Constant(property.GetJsonPropertyName()), - Expression.Constant(property.ClrType)), - property.ClrType); + resultExpression = Expression.Call( + ExtractJsonPropertyMethodInfo.MakeGenericMethod(property.ClrType), + jsonElementParameter, + Expression.Constant(property.GetJsonPropertyName()), + Expression.Constant(nullable)); } if (_detailedErrorsEnabled) diff --git a/src/EFCore.Relational/Query/SqlExpressions/JsonScalarExpression.cs b/src/EFCore.Relational/Query/SqlExpressions/JsonScalarExpression.cs index 1a568204cf9..7e6f047333d 100644 --- a/src/EFCore.Relational/Query/SqlExpressions/JsonScalarExpression.cs +++ b/src/EFCore.Relational/Query/SqlExpressions/JsonScalarExpression.cs @@ -26,7 +26,7 @@ public JsonScalarExpression( IProperty property, IReadOnlyList path, bool nullable) - : this(jsonColumn, path, property.ClrType, property.FindRelationalTypeMapping()!, nullable) + : this(jsonColumn, path, property.ClrType.UnwrapNullableType(), property.FindRelationalTypeMapping()!, nullable) { } diff --git a/test/EFCore.Relational.Specification.Tests/Query/JsonQueryAdHocTestBase.cs b/test/EFCore.Relational.Specification.Tests/Query/JsonQueryAdHocTestBase.cs new file mode 100644 index 00000000000..ae2442bd052 --- /dev/null +++ b/test/EFCore.Relational.Specification.Tests/Query/JsonQueryAdHocTestBase.cs @@ -0,0 +1,86 @@ +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. + +namespace Microsoft.EntityFrameworkCore.Query; + +public abstract class JsonQueryAdHocTestBase : NonSharedModelTestBase +{ + protected JsonQueryAdHocTestBase(ITestOutputHelper testOutputHelper) + { + //TestSqlLoggerFactory.SetTestOutputHelper(testOutputHelper); + } + + protected override string StoreName + => "JsonQueryAdHocTest"; + + [ConditionalTheory] + [MemberData(nameof(IsAsyncData))] + public virtual async Task Optional_json_properties_materialized_as_null_when_the_element_in_json_is_not_present(bool async) + { + var contextFactory = await InitializeAsync(seed: Seed29219); + using (var context = contextFactory.CreateContext()) + { + var query = context.Entities.Where(x => x.Id == 3); + + var result = async + ? await query.SingleAsync() + : query.Single(); + + Assert.Equal(3, result.Id); + Assert.Equal(null, result.Reference.NullableScalar); + Assert.Equal(null, result.Collection[0].NullableScalar); + } + } + + [ConditionalTheory] + [MemberData(nameof(IsAsyncData))] + public virtual async Task Can_project_nullable_json_property_when_the_element_in_json_is_not_present(bool async) + { + var contextFactory = await InitializeAsync(seed: Seed29219); + using (var context = contextFactory.CreateContext()) + { + var query = context.Entities.OrderBy(x => x.Id).Select(x => x.Reference.NullableScalar); + + var result = async + ? await query.ToListAsync() + : query.ToList(); + + Assert.Equal(3, result.Count); + Assert.Equal(11, result[0]); + Assert.Equal(null, result[1]); + Assert.Equal(null, result[2]); + } + } + + protected abstract void Seed29219(MyContext29219 ctx); + + protected class MyContext29219 : DbContext + { + public MyContext29219(DbContextOptions options) + : base(options) + { + } + + public DbSet Entities { get; set; } + + protected override void OnModelCreating(ModelBuilder modelBuilder) + { + modelBuilder.Entity().Property(x => x.Id).ValueGeneratedNever(); + modelBuilder.Entity().OwnsOne(x => x.Reference).ToJson(); + modelBuilder.Entity().OwnsMany(x => x.Collection).ToJson(); + } + } + + public class MyEntity29219 + { + public int Id { get; set; } + public MyJsonEntity29219 Reference { get; set; } + public List Collection { get; set; } + } + + public class MyJsonEntity29219 + { + public int NonNullableScalar { get; set; } + public int? NullableScalar { get; set; } + } +} diff --git a/test/EFCore.Relational.Specification.Tests/Query/JsonQueryFixtureBase.cs b/test/EFCore.Relational.Specification.Tests/Query/JsonQueryFixtureBase.cs index bfefb656232..6e9d16bba1d 100644 --- a/test/EFCore.Relational.Specification.Tests/Query/JsonQueryFixtureBase.cs +++ b/test/EFCore.Relational.Specification.Tests/Query/JsonQueryFixtureBase.cs @@ -297,6 +297,7 @@ private static void AssertOwnedBranch(JsonOwnedBranch expected, JsonOwnedBranch Assert.Equal(expected.Date, actual.Date); Assert.Equal(expected.Fraction, actual.Fraction); Assert.Equal(expected.Enum, actual.Enum); + Assert.Equal(expected.NullableEnum, actual.NullableEnum); AssertOwnedLeaf(expected.OwnedReferenceLeaf, actual.OwnedReferenceLeaf); Assert.Equal(expected.OwnedCollectionLeaf.Count, actual.OwnedCollectionLeaf.Count); @@ -345,6 +346,12 @@ public static void AssertAllTypes(JsonOwnedAllTypes expected, JsonOwnedAllTypes Assert.Equal(expected.TestUnsignedInt16, actual.TestUnsignedInt16); Assert.Equal(expected.TestUnsignedInt32, actual.TestUnsignedInt32); Assert.Equal(expected.TestUnsignedInt64, actual.TestUnsignedInt64); + Assert.Equal(expected.TestNullableInt32, actual.TestNullableInt32); + Assert.Equal(expected.TestEnum, actual.TestEnum); + Assert.Equal(expected.TestEnumWithIntConverter, actual.TestEnumWithIntConverter); + Assert.Equal(expected.TestNullableEnum, actual.TestNullableEnum); + Assert.Equal(expected.TestNullableEnumWithIntConverter, actual.TestNullableEnumWithIntConverter); + Assert.Equal(expected.TestNullableEnumWithConverterThatHandlesNulls, actual.TestNullableEnumWithConverterThatHandlesNulls); } protected override string StoreName { get; } = "JsonQueryTest"; @@ -496,6 +503,27 @@ protected override void OnModelCreating(ModelBuilder modelBuilder, DbContext con { b.ToJson(); b.Property(x => x.TestDecimal).HasPrecision(18, 3); + b.Property(x => x.TestEnumWithIntConverter).HasConversion(); + b.Property(x => x.TestNullableEnumWithIntConverter).HasConversion(); + b.Property(x => x.TestNullableEnumWithConverterThatHandlesNulls).HasConversion( + new ValueConverter( + x => x == null + ? "Null" + : x == JsonEnum.One + ? "One" + : x == JsonEnum.Two + ? "Two" + : x == JsonEnum.Three + ? "Three" + : "INVALID", + x => x == "One" + ? JsonEnum.One + : x == "Two" + ? JsonEnum.Two + : x == "Three" + ? JsonEnum.Three + : null, + convertsNulls: true)); }); modelBuilder.Entity().OwnsMany( x => x.Collection, b => diff --git a/test/EFCore.Relational.Specification.Tests/Query/JsonQueryTestBase.cs b/test/EFCore.Relational.Specification.Tests/Query/JsonQueryTestBase.cs index a29be984da2..7450891771c 100644 --- a/test/EFCore.Relational.Specification.Tests/Query/JsonQueryTestBase.cs +++ b/test/EFCore.Relational.Specification.Tests/Query/JsonQueryTestBase.cs @@ -726,7 +726,7 @@ public virtual Task Json_all_types_entity_projection(bool async) => AssertQuery( async, ss => ss.Set(), - entryCount: 3); + entryCount: 6); [ConditionalTheory] [MemberData(nameof(IsAsyncData))] @@ -752,6 +752,12 @@ public virtual Task Json_all_types_projection_individual_properties(bool async) x.Reference.TestTimeSpan, x.Reference.TestUnsignedInt16, x.Reference.TestUnsignedInt32, - x.Reference.TestUnsignedInt64 + x.Reference.TestUnsignedInt64, + x.Reference.TestNullableInt32, + x.Reference.TestEnum, + x.Reference.TestEnumWithIntConverter, + x.Reference.TestNullableEnum, + x.Reference.TestNullableEnumWithIntConverter, + x.Reference.TestNullableEnumWithConverterThatHandlesNulls, })); } diff --git a/test/EFCore.Relational.Specification.Tests/TestModels/JsonQuery/JsonOwnedAllTypes.cs b/test/EFCore.Relational.Specification.Tests/TestModels/JsonQuery/JsonOwnedAllTypes.cs index 340bb7afddd..be1b3a41fc3 100644 --- a/test/EFCore.Relational.Specification.Tests/TestModels/JsonQuery/JsonOwnedAllTypes.cs +++ b/test/EFCore.Relational.Specification.Tests/TestModels/JsonQuery/JsonOwnedAllTypes.cs @@ -22,4 +22,10 @@ public class JsonOwnedAllTypes public ulong TestUnsignedInt64 { get; set; } public char TestCharacter { get; set; } public sbyte TestSignedByte { get; set; } + public int? TestNullableInt32 { get; set; } + public JsonEnum TestEnum { get; set; } + public JsonEnum TestEnumWithIntConverter { get; set; } + public JsonEnum? TestNullableEnum { get; set; } + public JsonEnum? TestNullableEnumWithIntConverter { get; set; } + public JsonEnum? TestNullableEnumWithConverterThatHandlesNulls { get; set; } } diff --git a/test/EFCore.Relational.Specification.Tests/TestModels/JsonQuery/JsonOwnedBranch.cs b/test/EFCore.Relational.Specification.Tests/TestModels/JsonQuery/JsonOwnedBranch.cs index db17d6f0af0..5a944f4dde3 100644 --- a/test/EFCore.Relational.Specification.Tests/TestModels/JsonQuery/JsonOwnedBranch.cs +++ b/test/EFCore.Relational.Specification.Tests/TestModels/JsonQuery/JsonOwnedBranch.cs @@ -10,6 +10,8 @@ public class JsonOwnedBranch public JsonEnum Enum { get; set; } + public JsonEnum? NullableEnum { get; set; } + public JsonOwnedLeaf OwnedReferenceLeaf { get; set; } public List OwnedCollectionLeaf { get; set; } } diff --git a/test/EFCore.Relational.Specification.Tests/TestModels/JsonQuery/JsonQueryData.cs b/test/EFCore.Relational.Specification.Tests/TestModels/JsonQuery/JsonQueryData.cs index 3b04fb81f5a..588701d60ac 100644 --- a/test/EFCore.Relational.Specification.Tests/TestModels/JsonQuery/JsonQueryData.cs +++ b/test/EFCore.Relational.Specification.Tests/TestModels/JsonQuery/JsonQueryData.cs @@ -45,6 +45,7 @@ public static IReadOnlyList CreateJsonEntitiesBasic() Date = new DateTime(2100, 1, 1), Fraction = 10.0M, Enum = JsonEnum.One, + NullableEnum = null, OwnedReferenceLeaf = e1_r_r_r, OwnedCollectionLeaf = new List { e1_r_r_c1, e1_r_r_c2 } }; @@ -67,6 +68,7 @@ public static IReadOnlyList CreateJsonEntitiesBasic() Date = new DateTime(2101, 1, 1), Fraction = 10.1M, Enum = JsonEnum.Two, + NullableEnum = JsonEnum.One, OwnedReferenceLeaf = e1_r_c1_r, OwnedCollectionLeaf = new List { e1_r_c1_c1, e1_r_c1_c2 } }; @@ -89,6 +91,7 @@ public static IReadOnlyList CreateJsonEntitiesBasic() Date = new DateTime(2102, 1, 1), Fraction = 10.2M, Enum = JsonEnum.Three, + NullableEnum = JsonEnum.Two, OwnedReferenceLeaf = e1_r_c2_r, OwnedCollectionLeaf = new List { e1_r_c2_c1, e1_r_c2_c2 } }; @@ -123,6 +126,7 @@ public static IReadOnlyList CreateJsonEntitiesBasic() Date = new DateTime(2110, 1, 1), Fraction = 11.0M, Enum = JsonEnum.One, + NullableEnum = null, OwnedReferenceLeaf = e1_c1_r_r, OwnedCollectionLeaf = new List { e1_c1_r_c1, e1_c1_r_c2 } }; @@ -145,6 +149,7 @@ public static IReadOnlyList CreateJsonEntitiesBasic() Date = new DateTime(2111, 1, 1), Fraction = 11.1M, Enum = JsonEnum.Two, + NullableEnum = JsonEnum.One, OwnedReferenceLeaf = e1_c1_c1_r, OwnedCollectionLeaf = new List { e1_c1_c1_c1, e1_c1_c1_c2 } }; @@ -167,6 +172,7 @@ public static IReadOnlyList CreateJsonEntitiesBasic() Date = new DateTime(2112, 1, 1), Fraction = 11.2M, Enum = JsonEnum.Three, + NullableEnum = JsonEnum.Two, OwnedReferenceLeaf = e1_c1_c2_r, OwnedCollectionLeaf = new List { e1_c1_c2_c1, e1_c1_c2_c2 } }; @@ -201,6 +207,7 @@ public static IReadOnlyList CreateJsonEntitiesBasic() Date = new DateTime(2120, 1, 1), Fraction = 12.0M, Enum = JsonEnum.Three, + NullableEnum = JsonEnum.Two, OwnedReferenceLeaf = e1_c2_r_r, OwnedCollectionLeaf = new List { e1_c2_r_c1, e1_c2_r_c2 } }; @@ -223,6 +230,7 @@ public static IReadOnlyList CreateJsonEntitiesBasic() Date = new DateTime(2121, 1, 1), Fraction = 12.1M, Enum = JsonEnum.Two, + NullableEnum = JsonEnum.One, OwnedReferenceLeaf = e1_c2_c1_r, OwnedCollectionLeaf = new List { e1_c2_c1_c1, e1_c2_c1_c2 } }; @@ -245,6 +253,7 @@ public static IReadOnlyList CreateJsonEntitiesBasic() Date = new DateTime(2122, 1, 1), Fraction = 12.2M, Enum = JsonEnum.One, + NullableEnum = null, OwnedReferenceLeaf = e1_c2_c2_r, OwnedCollectionLeaf = new List { e1_c2_c2_c1, e1_c2_c2_c2 } }; @@ -465,6 +474,7 @@ public static IReadOnlyList CreateJsonEntitiesInherit Date = new DateTime(2010, 1, 1), Fraction = 1.0M, Enum = JsonEnum.One, + NullableEnum = null, OwnedReferenceLeaf = b1_r_r, OwnedCollectionLeaf = new List { b1_r_c1, b1_r_c2 } }; @@ -480,6 +490,7 @@ public static IReadOnlyList CreateJsonEntitiesInherit Date = new DateTime(2011, 1, 1), Fraction = 11.1M, Enum = JsonEnum.Three, + NullableEnum = JsonEnum.Two, OwnedReferenceLeaf = b1_c1_r, OwnedCollectionLeaf = new List { b1_c1_c1, b1_c1_c2 } }; @@ -495,6 +506,7 @@ public static IReadOnlyList CreateJsonEntitiesInherit Date = new DateTime(2012, 1, 1), Fraction = 12.1M, Enum = JsonEnum.Two, + NullableEnum = JsonEnum.One, OwnedReferenceLeaf = b1_c2_r, OwnedCollectionLeaf = new List { b1_c2_c1, b1_c2_c2 } }; @@ -510,6 +522,7 @@ public static IReadOnlyList CreateJsonEntitiesInherit Date = new DateTime(2020, 1, 1), Fraction = 2.0M, Enum = JsonEnum.Two, + NullableEnum = JsonEnum.One, OwnedReferenceLeaf = b2_r_r, OwnedCollectionLeaf = new List { b2_r_c1, b2_r_c2 } }; @@ -525,6 +538,7 @@ public static IReadOnlyList CreateJsonEntitiesInherit Date = new DateTime(2021, 1, 1), Fraction = 21.1M, Enum = JsonEnum.Three, + NullableEnum = JsonEnum.Two, OwnedReferenceLeaf = b2_c1_r, OwnedCollectionLeaf = new List { b2_c1_c1, b2_c1_c2 } }; @@ -540,6 +554,7 @@ public static IReadOnlyList CreateJsonEntitiesInherit Date = new DateTime(2022, 1, 1), Fraction = 22.1M, Enum = JsonEnum.One, + NullableEnum = null, OwnedReferenceLeaf = b2_c2_r, OwnedCollectionLeaf = new List { b2_c2_c1, b2_c2_c2 } }; @@ -555,6 +570,7 @@ public static IReadOnlyList CreateJsonEntitiesInherit Date = new DateTime(2220, 1, 1), Fraction = 22.0M, Enum = JsonEnum.One, + NullableEnum = null, OwnedReferenceLeaf = d2_r_r, OwnedCollectionLeaf = new List { d2_r_c1, d2_r_c2 } }; @@ -570,6 +586,7 @@ public static IReadOnlyList CreateJsonEntitiesInherit Date = new DateTime(2221, 1, 1), Fraction = 221.1M, Enum = JsonEnum.Two, + NullableEnum = JsonEnum.One, OwnedReferenceLeaf = d2_c1_r, OwnedCollectionLeaf = new List { d2_c1_c1, d2_c1_c2 } }; @@ -585,6 +602,7 @@ public static IReadOnlyList CreateJsonEntitiesInherit Date = new DateTime(2222, 1, 1), Fraction = 222.1M, Enum = JsonEnum.Three, + NullableEnum = JsonEnum.Two, OwnedReferenceLeaf = d2_c2_r, OwnedCollectionLeaf = new List { d2_c2_c1, d2_c2_c2 } }; @@ -612,7 +630,7 @@ public static IReadOnlyList CreateJsonEntitiesInherit public static IReadOnlyList CreateJsonEntitiesAllTypes() { - var r = new JsonOwnedAllTypes + var r1 = new JsonOwnedAllTypes { TestInt16 = -1234, TestInt32 = -123456789, @@ -631,9 +649,42 @@ public static IReadOnlyList CreateJsonEntitiesAllTypes() TestUnsignedInt64 = 1234567890123456789UL, TestCharacter = 'a', TestSignedByte = -128, + TestNullableInt32 = 78, + TestEnum = JsonEnum.One, + TestEnumWithIntConverter = JsonEnum.Two, + TestNullableEnum = JsonEnum.One, + TestNullableEnumWithIntConverter = JsonEnum.Two, + TestNullableEnumWithConverterThatHandlesNulls = JsonEnum.Three, + }; + + var r2 = new JsonOwnedAllTypes + { + TestInt16 = -123, + TestInt32 = -12356789, + TestInt64 = -123567890123456789L, + TestDouble = -1.2346789, + TestDecimal = -123567890.01M, + TestDateTime = DateTime.Parse("01/01/3000 12:34:56"), + TestDateTimeOffset = new DateTimeOffset(DateTime.Parse("01/01/3000 12:34:56"), TimeSpan.FromHours(-8.0)), + TestTimeSpan = new TimeSpan(0, 5, 9, 8, 7), + TestSingle = -1.24F, + TestBoolean = true, + TestByte = 25, + TestGuid = new Guid("12345678-1243-4321-7777-987654321000"), + TestUnsignedInt16 = 134, + TestUnsignedInt32 = 123565789U, + TestUnsignedInt64 = 123567890123456789UL, + TestCharacter = 'b', + TestSignedByte = -18, + TestNullableInt32 = null, + TestEnum = JsonEnum.Two, + TestEnumWithIntConverter = JsonEnum.Three, + TestNullableEnum = null, + TestNullableEnumWithIntConverter = null, + TestNullableEnumWithConverterThatHandlesNulls = null, }; - var c = new JsonOwnedAllTypes + var c1 = new JsonOwnedAllTypes { TestInt16 = -12, TestInt32 = -12345, @@ -652,6 +703,39 @@ public static IReadOnlyList CreateJsonEntitiesAllTypes() TestUnsignedInt64 = 1234567867UL, TestCharacter = 'h', TestSignedByte = -18, + TestNullableInt32 = 90, + TestEnum = JsonEnum.One, + TestEnumWithIntConverter = JsonEnum.Two, + TestNullableEnum = JsonEnum.One, + TestNullableEnumWithIntConverter = JsonEnum.Three, + TestNullableEnumWithConverterThatHandlesNulls = JsonEnum.Two, + }; + + var c2 = new JsonOwnedAllTypes + { + TestInt16 = -1, + TestInt32 = -1245, + TestInt64 = -123567890L, + TestDouble = -1.235, + TestDecimal = -12350.01M, + TestDateTime = DateTime.Parse("11/11/3100 12:34:56"), + TestDateTimeOffset = new DateTimeOffset(DateTime.Parse("11/11/3200 12:34:56"), TimeSpan.FromHours(-5.0)), + TestTimeSpan = new TimeSpan(0, 6, 5, 2, 3), + TestSingle = -1.4F, + TestBoolean = false, + TestByte = 25, + TestGuid = new Guid("00000000-0000-0000-0000-000000100000"), + TestUnsignedInt16 = 1, + TestUnsignedInt32 = 1245U, + TestUnsignedInt64 = 124567867UL, + TestCharacter = 'g', + TestSignedByte = -8, + TestNullableInt32 = null, + TestEnum = JsonEnum.Two, + TestEnumWithIntConverter = JsonEnum.Three, + TestNullableEnum = null, + TestNullableEnumWithIntConverter = null, + TestNullableEnumWithConverterThatHandlesNulls = null, }; return new List @@ -659,8 +743,14 @@ public static IReadOnlyList CreateJsonEntitiesAllTypes() new() { Id = 1, - Reference = r, - Collection = new List { c } + Reference = r1, + Collection = new List { c1 } + }, + new() + { + Id = 2, + Reference = r2, + Collection = new List { c2 } } }; } diff --git a/test/EFCore.Relational.Specification.Tests/Update/JsonUpdateTestBase.cs b/test/EFCore.Relational.Specification.Tests/Update/JsonUpdateTestBase.cs index 883a3d374d0..12231b31047 100644 --- a/test/EFCore.Relational.Specification.Tests/Update/JsonUpdateTestBase.cs +++ b/test/EFCore.Relational.Specification.Tests/Update/JsonUpdateTestBase.cs @@ -659,7 +659,7 @@ public virtual Task Edit_single_property_bool() async context => { var query = await context.JsonEntitiesAllTypes.ToListAsync(); - var entity = query.Single(); + var entity = query.Single(x => x.Id == 1); entity.Reference.TestBoolean = false; entity.Collection[0].TestBoolean = true; @@ -668,7 +668,7 @@ public virtual Task Edit_single_property_bool() }, async context => { - var result = await context.Set().SingleAsync(); + var result = await context.Set().SingleAsync(x => x.Id == 1); Assert.Equal(false, result.Reference.TestBoolean); Assert.Equal(true, result.Collection[0].TestBoolean); }); @@ -681,7 +681,7 @@ public virtual Task Edit_single_property_byte() async context => { var query = await context.JsonEntitiesAllTypes.ToListAsync(); - var entity = query.Single(); + var entity = query.Single(x => x.Id == 1); entity.Reference.TestByte = 25; entity.Collection[0].TestByte = 14; @@ -690,7 +690,7 @@ public virtual Task Edit_single_property_byte() }, async context => { - var result = await context.Set().SingleAsync(); + var result = await context.Set().SingleAsync(x => x.Id == 1); Assert.Equal(25, result.Reference.TestByte); Assert.Equal(14, result.Collection[0].TestByte); }); @@ -703,7 +703,7 @@ public virtual Task Edit_single_property_char() async context => { var query = await context.JsonEntitiesAllTypes.ToListAsync(); - var entity = query.Single(); + var entity = query.Single(x => x.Id == 1); entity.Reference.TestCharacter = 't'; entity.Collection[0].TestCharacter = 'h'; @@ -712,7 +712,7 @@ public virtual Task Edit_single_property_char() }, async context => { - var result = await context.Set().SingleAsync(); + var result = await context.Set().SingleAsync(x => x.Id == 1); Assert.Equal('t', result.Reference.TestCharacter); Assert.Equal('h', result.Collection[0].TestCharacter); }); @@ -725,7 +725,7 @@ public virtual Task Edit_single_property_datetime() async context => { var query = await context.JsonEntitiesAllTypes.ToListAsync(); - var entity = query.Single(); + var entity = query.Single(x => x.Id == 1); entity.Reference.TestDateTime = DateTime.Parse("01/01/3000 12:34:56"); entity.Collection[0].TestDateTime = DateTime.Parse("01/01/3000 12:34:56"); @@ -734,7 +734,7 @@ public virtual Task Edit_single_property_datetime() }, async context => { - var result = await context.Set().SingleAsync(); + var result = await context.Set().SingleAsync(x => x.Id == 1); Assert.Equal(DateTime.Parse("01/01/3000 12:34:56"), result.Reference.TestDateTime); Assert.Equal(DateTime.Parse("01/01/3000 12:34:56"), result.Collection[0].TestDateTime); }); @@ -747,7 +747,7 @@ public virtual Task Edit_single_property_datetimeoffset() async context => { var query = await context.JsonEntitiesAllTypes.ToListAsync(); - var entity = query.Single(); + var entity = query.Single(x => x.Id == 1); entity.Reference.TestDateTimeOffset = new DateTimeOffset(DateTime.Parse("01/01/3000 12:34:56"), TimeSpan.FromHours(-4.0)); entity.Collection[0].TestDateTimeOffset = new DateTimeOffset( DateTime.Parse("01/01/3000 12:34:56"), TimeSpan.FromHours(-4.0)); @@ -757,7 +757,7 @@ public virtual Task Edit_single_property_datetimeoffset() }, async context => { - var result = await context.Set().SingleAsync(); + var result = await context.Set().SingleAsync(x => x.Id == 1); Assert.Equal( new DateTimeOffset(DateTime.Parse("01/01/3000 12:34:56"), TimeSpan.FromHours(-4.0)), result.Reference.TestDateTimeOffset); @@ -774,7 +774,7 @@ public virtual Task Edit_single_property_decimal() async context => { var query = await context.JsonEntitiesAllTypes.ToListAsync(); - var entity = query.Single(); + var entity = query.Single(x => x.Id == 1); entity.Reference.TestDecimal = -13579.01M; entity.Collection[0].TestDecimal = -13579.01M; @@ -783,7 +783,7 @@ public virtual Task Edit_single_property_decimal() }, async context => { - var result = await context.Set().SingleAsync(); + var result = await context.Set().SingleAsync(x => x.Id == 1); Assert.Equal(-13579.01M, result.Reference.TestDecimal); Assert.Equal(-13579.01M, result.Collection[0].TestDecimal); }); @@ -796,7 +796,7 @@ public virtual Task Edit_single_property_double() async context => { var query = await context.JsonEntitiesAllTypes.ToListAsync(); - var entity = query.Single(); + var entity = query.Single(x => x.Id == 1); entity.Reference.TestDouble = -1.23579; entity.Collection[0].TestDouble = -1.23579; @@ -805,7 +805,7 @@ public virtual Task Edit_single_property_double() }, async context => { - var result = await context.Set().SingleAsync(); + var result = await context.Set().SingleAsync(x => x.Id == 1); Assert.Equal(-1.23579, result.Reference.TestDouble); Assert.Equal(-1.23579, result.Collection[0].TestDouble); }); @@ -818,7 +818,7 @@ public virtual Task Edit_single_property_guid() async context => { var query = await context.JsonEntitiesAllTypes.ToListAsync(); - var entity = query.Single(); + var entity = query.Single(x => x.Id == 1); entity.Reference.TestGuid = new Guid("12345678-1234-4321-5555-987654321000"); entity.Collection[0].TestGuid = new Guid("12345678-1234-4321-5555-987654321000"); @@ -827,7 +827,7 @@ public virtual Task Edit_single_property_guid() }, async context => { - var result = await context.Set().SingleAsync(); + var result = await context.Set().SingleAsync(x => x.Id == 1); Assert.Equal(new Guid("12345678-1234-4321-5555-987654321000"), result.Reference.TestGuid); Assert.Equal(new Guid("12345678-1234-4321-5555-987654321000"), result.Collection[0].TestGuid); }); @@ -840,7 +840,7 @@ public virtual Task Edit_single_property_int16() async context => { var query = await context.JsonEntitiesAllTypes.ToListAsync(); - var entity = query.Single(); + var entity = query.Single(x => x.Id == 1); entity.Reference.TestInt16 = -3234; entity.Collection[0].TestInt16 = -3234; @@ -849,7 +849,7 @@ public virtual Task Edit_single_property_int16() }, async context => { - var result = await context.Set().SingleAsync(); + var result = await context.Set().SingleAsync(x => x.Id == 1); Assert.Equal(-3234, result.Reference.TestInt16); Assert.Equal(-3234, result.Collection[0].TestInt16); }); @@ -862,7 +862,7 @@ public virtual Task Edit_single_property_int32() async context => { var query = await context.JsonEntitiesAllTypes.ToListAsync(); - var entity = query.Single(); + var entity = query.Single(x => x.Id == 1); entity.Reference.TestInt32 = -3234; entity.Collection[0].TestInt32 = -3234; @@ -871,7 +871,7 @@ public virtual Task Edit_single_property_int32() }, async context => { - var result = await context.Set().SingleAsync(); + var result = await context.Set().SingleAsync(x => x.Id == 1); Assert.Equal(-3234, result.Reference.TestInt32); Assert.Equal(-3234, result.Collection[0].TestInt32); }); @@ -884,7 +884,7 @@ public virtual Task Edit_single_property_int64() async context => { var query = await context.JsonEntitiesAllTypes.ToListAsync(); - var entity = query.Single(); + var entity = query.Single(x => x.Id == 1); entity.Reference.TestInt64 = -3234; entity.Collection[0].TestInt64 = -3234; @@ -893,7 +893,7 @@ public virtual Task Edit_single_property_int64() }, async context => { - var result = await context.Set().SingleAsync(); + var result = await context.Set().SingleAsync(x => x.Id == 1); Assert.Equal(-3234, result.Reference.TestInt64); Assert.Equal(-3234, result.Collection[0].TestInt64); }); @@ -906,7 +906,7 @@ public virtual Task Edit_single_property_signed_byte() async context => { var query = await context.JsonEntitiesAllTypes.ToListAsync(); - var entity = query.Single(); + var entity = query.Single(x => x.Id == 1); entity.Reference.TestSignedByte = -108; entity.Collection[0].TestSignedByte = -108; @@ -915,7 +915,7 @@ public virtual Task Edit_single_property_signed_byte() }, async context => { - var result = await context.Set().SingleAsync(); + var result = await context.Set().SingleAsync(x => x.Id == 1); Assert.Equal(-108, result.Reference.TestSignedByte); Assert.Equal(-108, result.Collection[0].TestSignedByte); }); @@ -928,7 +928,7 @@ public virtual Task Edit_single_property_single() async context => { var query = await context.JsonEntitiesAllTypes.ToListAsync(); - var entity = query.Single(); + var entity = query.Single(x => x.Id == 1); entity.Reference.TestSingle = -7.234F; entity.Collection[0].TestSingle = -7.234F; @@ -937,7 +937,7 @@ public virtual Task Edit_single_property_single() }, async context => { - var result = await context.Set().SingleAsync(); + var result = await context.Set().SingleAsync(x => x.Id == 1); Assert.Equal(-7.234F, result.Reference.TestSingle); Assert.Equal(-7.234F, result.Collection[0].TestSingle); }); @@ -950,7 +950,7 @@ public virtual Task Edit_single_property_timespan() async context => { var query = await context.JsonEntitiesAllTypes.ToListAsync(); - var entity = query.Single(); + var entity = query.Single(x => x.Id == 1); entity.Reference.TestTimeSpan = new TimeSpan(0, 10, 1, 1, 7); entity.Collection[0].TestTimeSpan = new TimeSpan(0, 10, 1, 1, 7); @@ -959,7 +959,7 @@ public virtual Task Edit_single_property_timespan() }, async context => { - var result = await context.Set().SingleAsync(); + var result = await context.Set().SingleAsync(x => x.Id == 1); Assert.Equal(new TimeSpan(0, 10, 1, 1, 7), result.Reference.TestTimeSpan); Assert.Equal(new TimeSpan(0, 10, 1, 1, 7), result.Collection[0].TestTimeSpan); }); @@ -972,7 +972,7 @@ public virtual Task Edit_single_property_uint16() async context => { var query = await context.JsonEntitiesAllTypes.ToListAsync(); - var entity = query.Single(); + var entity = query.Single(x => x.Id == 1); entity.Reference.TestUnsignedInt16 = 1534; entity.Collection[0].TestUnsignedInt16 = 1534; @@ -981,7 +981,7 @@ public virtual Task Edit_single_property_uint16() }, async context => { - var result = await context.Set().SingleAsync(); + var result = await context.Set().SingleAsync(x => x.Id == 1); Assert.Equal(1534, result.Reference.TestUnsignedInt16); Assert.Equal(1534, result.Collection[0].TestUnsignedInt16); }); @@ -994,7 +994,7 @@ public virtual Task Edit_single_property_uint32() async context => { var query = await context.JsonEntitiesAllTypes.ToListAsync(); - var entity = query.Single(); + var entity = query.Single(x => x.Id == 1); entity.Reference.TestUnsignedInt32 = 1237775789U; entity.Collection[0].TestUnsignedInt32 = 1237775789U; @@ -1003,7 +1003,7 @@ public virtual Task Edit_single_property_uint32() }, async context => { - var result = await context.Set().SingleAsync(); + var result = await context.Set().SingleAsync(x => x.Id == 1); Assert.Equal(1237775789U, result.Reference.TestUnsignedInt32); Assert.Equal(1237775789U, result.Collection[0].TestUnsignedInt32); }); @@ -1016,7 +1016,7 @@ public virtual Task Edit_single_property_uint64() async context => { var query = await context.JsonEntitiesAllTypes.ToListAsync(); - var entity = query.Single(); + var entity = query.Single(x => x.Id == 1); entity.Reference.TestUnsignedInt64 = 1234555555123456789UL; entity.Collection[0].TestUnsignedInt64 = 1234555555123456789UL; @@ -1025,11 +1025,231 @@ public virtual Task Edit_single_property_uint64() }, async context => { - var result = await context.Set().SingleAsync(); + var result = await context.Set().SingleAsync(x => x.Id == 1); Assert.Equal(1234555555123456789UL, result.Reference.TestUnsignedInt64); Assert.Equal(1234555555123456789UL, result.Collection[0].TestUnsignedInt64); }); + [ConditionalFact] + public virtual Task Edit_single_property_nullable_int32() + => TestHelpers.ExecuteWithStrategyInTransactionAsync( + CreateContext, + UseTransaction, + async context => + { + var query = await context.JsonEntitiesAllTypes.ToListAsync(); + var entity = query.Single(x => x.Id == 1); + entity.Reference.TestNullableInt32 = 64528; + entity.Collection[0].TestNullableInt32 = 122354; + + ClearLog(); + await context.SaveChangesAsync(); + }, + async context => + { + var result = await context.Set().SingleAsync(x => x.Id == 1); + Assert.Equal(64528, result.Reference.TestNullableInt32); + Assert.Equal(122354, result.Collection[0].TestNullableInt32); + }); + + [ConditionalFact] + public virtual Task Edit_single_property_nullable_int32_set_to_null() + => TestHelpers.ExecuteWithStrategyInTransactionAsync( + CreateContext, + UseTransaction, + async context => + { + var query = await context.JsonEntitiesAllTypes.ToListAsync(); + var entity = query.Single(x => x.Id == 1); + entity.Reference.TestNullableInt32 = null; + entity.Collection[0].TestNullableInt32 = null; + + ClearLog(); + await context.SaveChangesAsync(); + }, + async context => + { + var result = await context.Set().SingleAsync(x => x.Id == 1); + Assert.Equal(null, result.Reference.TestNullableInt32); + Assert.Equal(null, result.Collection[0].TestNullableInt32); + }); + + [ConditionalFact] + public virtual Task Edit_single_property_enum() + => TestHelpers.ExecuteWithStrategyInTransactionAsync( + CreateContext, + UseTransaction, + async context => + { + var query = await context.JsonEntitiesAllTypes.ToListAsync(); + var entity = query.Single(x => x.Id == 1); + entity.Reference.TestEnum = JsonEnum.Three; + entity.Collection[0].TestEnum = JsonEnum.Three; + + ClearLog(); + await context.SaveChangesAsync(); + }, + async context => + { + var result = await context.Set().SingleAsync(x => x.Id == 1); + Assert.Equal(JsonEnum.Three, result.Reference.TestEnum); + Assert.Equal(JsonEnum.Three, result.Collection[0].TestEnum); + }); + + [ConditionalFact] + public virtual Task Edit_single_property_enum_with_int_converter() + => TestHelpers.ExecuteWithStrategyInTransactionAsync( + CreateContext, + UseTransaction, + async context => + { + var query = await context.JsonEntitiesAllTypes.ToListAsync(); + var entity = query.Single(x => x.Id == 1); + entity.Reference.TestEnumWithIntConverter = JsonEnum.Three; + entity.Collection[0].TestEnumWithIntConverter = JsonEnum.Three; + + ClearLog(); + await context.SaveChangesAsync(); + }, + async context => + { + var result = await context.Set().SingleAsync(x => x.Id == 1); + Assert.Equal(JsonEnum.Three, result.Reference.TestEnumWithIntConverter); + Assert.Equal(JsonEnum.Three, result.Collection[0].TestEnumWithIntConverter); + }); + + [ConditionalFact] + public virtual Task Edit_single_property_nullable_enum() + => TestHelpers.ExecuteWithStrategyInTransactionAsync( + CreateContext, + UseTransaction, + async context => + { + var query = await context.JsonEntitiesAllTypes.ToListAsync(); + var entity = query.Single(x => x.Id == 1); + entity.Reference.TestEnum = JsonEnum.Three; + entity.Collection[0].TestEnum = JsonEnum.Three; + + ClearLog(); + await context.SaveChangesAsync(); + }, + async context => + { + var result = await context.Set().SingleAsync(x => x.Id == 1); + Assert.Equal(JsonEnum.Three, result.Reference.TestEnum); + Assert.Equal(JsonEnum.Three, result.Collection[0].TestEnum); + }); + + [ConditionalFact] + public virtual Task Edit_single_property_nullable_enum_set_to_null() + => TestHelpers.ExecuteWithStrategyInTransactionAsync( + CreateContext, + UseTransaction, + async context => + { + var query = await context.JsonEntitiesAllTypes.ToListAsync(); + var entity = query.Single(x => x.Id == 1); + entity.Reference.TestNullableEnum = null; + entity.Collection[0].TestNullableEnum = null; + + ClearLog(); + await context.SaveChangesAsync(); + }, + async context => + { + var result = await context.Set().SingleAsync(x => x.Id == 1); + Assert.Equal(null, result.Reference.TestNullableEnum); + Assert.Equal(null, result.Collection[0].TestNullableEnum); + }); + + [ConditionalFact] + public virtual Task Edit_single_property_nullable_enum_with_int_converter() + => TestHelpers.ExecuteWithStrategyInTransactionAsync( + CreateContext, + UseTransaction, + async context => + { + var query = await context.JsonEntitiesAllTypes.ToListAsync(); + var entity = query.Single(x => x.Id == 1); + entity.Reference.TestNullableEnumWithIntConverter = JsonEnum.Three; + entity.Collection[0].TestNullableEnumWithIntConverter = JsonEnum.One; + + ClearLog(); + await context.SaveChangesAsync(); + }, + async context => + { + var result = await context.Set().SingleAsync(x => x.Id == 1); + Assert.Equal(JsonEnum.Three, result.Reference.TestNullableEnumWithIntConverter); + Assert.Equal(JsonEnum.One, result.Collection[0].TestNullableEnumWithIntConverter); + }); + + [ConditionalFact] + public virtual Task Edit_single_property_nullable_enum_with_int_converter_set_to_null() + => TestHelpers.ExecuteWithStrategyInTransactionAsync( + CreateContext, + UseTransaction, + async context => + { + var query = await context.JsonEntitiesAllTypes.ToListAsync(); + var entity = query.Single(x => x.Id == 1); + entity.Reference.TestNullableEnumWithIntConverter = null; + entity.Collection[0].TestNullableEnumWithIntConverter = null; + + ClearLog(); + await context.SaveChangesAsync(); + }, + async context => + { + var result = await context.Set().SingleAsync(x => x.Id == 1); + Assert.Equal(null, result.Reference.TestNullableEnumWithIntConverter); + Assert.Equal(null, result.Collection[0].TestNullableEnumWithIntConverter); + }); + + [ConditionalFact] + public virtual Task Edit_single_property_nullable_enum_with_converter_that_handles_nulls() + => TestHelpers.ExecuteWithStrategyInTransactionAsync( + CreateContext, + UseTransaction, + async context => + { + var query = await context.JsonEntitiesAllTypes.ToListAsync(); + var entity = query.Single(x => x.Id == 1); + entity.Reference.TestNullableEnumWithConverterThatHandlesNulls = JsonEnum.One; + entity.Collection[0].TestNullableEnumWithConverterThatHandlesNulls = JsonEnum.Three; + + ClearLog(); + await context.SaveChangesAsync(); + }, + async context => + { + var result = await context.Set().SingleAsync(x => x.Id == 1); + Assert.Equal(JsonEnum.One, result.Reference.TestNullableEnumWithConverterThatHandlesNulls); + Assert.Equal(JsonEnum.Three, result.Collection[0].TestNullableEnumWithConverterThatHandlesNulls); + }); + + [ConditionalFact] + public virtual Task Edit_single_property_nullable_enum_with_converter_that_handles_nulls_set_to_null() + => TestHelpers.ExecuteWithStrategyInTransactionAsync( + CreateContext, + UseTransaction, + async context => + { + var query = await context.JsonEntitiesAllTypes.ToListAsync(); + var entity = query.Single(x => x.Id == 1); + entity.Reference.TestNullableEnumWithConverterThatHandlesNulls = null; + entity.Collection[0].TestNullableEnumWithConverterThatHandlesNulls = null; + + ClearLog(); + await context.SaveChangesAsync(); + }, + async context => + { + var result = await context.Set().SingleAsync(x => x.Id == 1); + Assert.Equal(null, result.Reference.TestNullableEnumWithConverterThatHandlesNulls); + Assert.Equal(null, result.Collection[0].TestNullableEnumWithConverterThatHandlesNulls); + }); + [ConditionalFact] public virtual Task Edit_two_properties_on_same_entity_updates_the_entire_entity() => TestHelpers.ExecuteWithStrategyInTransactionAsync( @@ -1038,7 +1258,7 @@ public virtual Task Edit_two_properties_on_same_entity_updates_the_entire_entity async context => { var query = await context.JsonEntitiesAllTypes.ToListAsync(); - var entity = query.Single(); + var entity = query.Single(x => x.Id == 1); entity.Reference.TestInt32 = 32; entity.Reference.TestInt64 = 64; entity.Collection[0].TestInt32 = 32; @@ -1049,7 +1269,7 @@ public virtual Task Edit_two_properties_on_same_entity_updates_the_entire_entity }, async context => { - var result = await context.Set().SingleAsync(); + var result = await context.Set().SingleAsync(x => x.Id == 1); Assert.Equal(32, result.Reference.TestInt32); Assert.Equal(64, result.Reference.TestInt64); Assert.Equal(32, result.Collection[0].TestInt32); diff --git a/test/EFCore.SqlServer.FunctionalTests/Query/JsonQueryAdHocSqlServerTest.cs b/test/EFCore.SqlServer.FunctionalTests/Query/JsonQueryAdHocSqlServerTest.cs new file mode 100644 index 00000000000..1095b9c192a --- /dev/null +++ b/test/EFCore.SqlServer.FunctionalTests/Query/JsonQueryAdHocSqlServerTest.cs @@ -0,0 +1,46 @@ +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. + +namespace Microsoft.EntityFrameworkCore.Query; + +public class JsonQueryAdHocSqlServerTest : JsonQueryAdHocTestBase +{ + public JsonQueryAdHocSqlServerTest(ITestOutputHelper testOutputHelper) + : base(testOutputHelper) + { + } + + protected override ITestStoreFactory TestStoreFactory + => SqlServerTestStoreFactory.Instance; + + protected override void Seed29219(MyContext29219 ctx) + { + var entity1 = new MyEntity29219 + { + Id = 1, + Reference = new MyJsonEntity29219 { NonNullableScalar = 10, NullableScalar = 11 }, + Collection = new List + { + new MyJsonEntity29219 { NonNullableScalar = 100, NullableScalar = 101 }, + new MyJsonEntity29219 { NonNullableScalar = 200, NullableScalar = 201 }, + new MyJsonEntity29219 { NonNullableScalar = 300, NullableScalar = null }, + } + }; + + var entity2 = new MyEntity29219 + { + Id = 2, + Reference = new MyJsonEntity29219 { NonNullableScalar = 20, NullableScalar = null }, + Collection = new List + { + new MyJsonEntity29219 { NonNullableScalar = 1001, NullableScalar = null }, + } + }; + + ctx.Entities.AddRange(entity1, entity2); + ctx.SaveChanges(); + + ctx.Database.ExecuteSqlRaw(@"INSERT INTO [Entities] ([Id], [Reference], [Collection]) +VALUES(3, N'{{ ""NonNullableScalar"" : 30 }}', N'[{{ ""NonNullableScalar"" : 10001 }}]')"); + } +} diff --git a/test/EFCore.SqlServer.FunctionalTests/Query/JsonQuerySqlServerTest.cs b/test/EFCore.SqlServer.FunctionalTests/Query/JsonQuerySqlServerTest.cs index 7d5e2f3d440..919b9d0acdd 100644 --- a/test/EFCore.SqlServer.FunctionalTests/Query/JsonQuerySqlServerTest.cs +++ b/test/EFCore.SqlServer.FunctionalTests/Query/JsonQuerySqlServerTest.cs @@ -617,7 +617,7 @@ public override async Task Json_all_types_projection_individual_properties(bool await base.Json_all_types_projection_individual_properties(async); AssertSql( - @"SELECT CAST(JSON_VALUE([j].[Reference],'$.TestBoolean') AS bit) AS [TestBoolean], CAST(JSON_VALUE([j].[Reference],'$.TestByte') AS tinyint) AS [TestByte], CAST(JSON_VALUE([j].[Reference],'$.TestCharacter') AS nvarchar(1)) AS [TestCharacter], CAST(JSON_VALUE([j].[Reference],'$.TestDateTime') AS datetime2) AS [TestDateTime], CAST(JSON_VALUE([j].[Reference],'$.TestDateTimeOffset') AS datetimeoffset) AS [TestDateTimeOffset], CAST(JSON_VALUE([j].[Reference],'$.TestDecimal') AS decimal(18,3)) AS [TestDecimal], CAST(JSON_VALUE([j].[Reference],'$.TestDouble') AS float) AS [TestDouble], CAST(JSON_VALUE([j].[Reference],'$.TestGuid') AS uniqueidentifier) AS [TestGuid], CAST(JSON_VALUE([j].[Reference],'$.TestInt16') AS smallint) AS [TestInt16], CAST(JSON_VALUE([j].[Reference],'$.TestInt32') AS int) AS [TestInt32], CAST(JSON_VALUE([j].[Reference],'$.TestInt64') AS bigint) AS [TestInt64], CAST(JSON_VALUE([j].[Reference],'$.TestSignedByte') AS smallint) AS [TestSignedByte], CAST(JSON_VALUE([j].[Reference],'$.TestSingle') AS real) AS [TestSingle], CAST(JSON_VALUE([j].[Reference],'$.TestTimeSpan') AS time) AS [TestTimeSpan], CAST(JSON_VALUE([j].[Reference],'$.TestUnsignedInt16') AS int) AS [TestUnsignedInt16], CAST(JSON_VALUE([j].[Reference],'$.TestUnsignedInt32') AS bigint) AS [TestUnsignedInt32], CAST(JSON_VALUE([j].[Reference],'$.TestUnsignedInt64') AS decimal(20,0)) AS [TestUnsignedInt64] + @"SELECT CAST(JSON_VALUE([j].[Reference],'$.TestBoolean') AS bit) AS [TestBoolean], CAST(JSON_VALUE([j].[Reference],'$.TestByte') AS tinyint) AS [TestByte], CAST(JSON_VALUE([j].[Reference],'$.TestCharacter') AS nvarchar(1)) AS [TestCharacter], CAST(JSON_VALUE([j].[Reference],'$.TestDateTime') AS datetime2) AS [TestDateTime], CAST(JSON_VALUE([j].[Reference],'$.TestDateTimeOffset') AS datetimeoffset) AS [TestDateTimeOffset], CAST(JSON_VALUE([j].[Reference],'$.TestDecimal') AS decimal(18,3)) AS [TestDecimal], CAST(JSON_VALUE([j].[Reference],'$.TestDouble') AS float) AS [TestDouble], CAST(JSON_VALUE([j].[Reference],'$.TestGuid') AS uniqueidentifier) AS [TestGuid], CAST(JSON_VALUE([j].[Reference],'$.TestInt16') AS smallint) AS [TestInt16], CAST(JSON_VALUE([j].[Reference],'$.TestInt32') AS int) AS [TestInt32], CAST(JSON_VALUE([j].[Reference],'$.TestInt64') AS bigint) AS [TestInt64], CAST(JSON_VALUE([j].[Reference],'$.TestSignedByte') AS smallint) AS [TestSignedByte], CAST(JSON_VALUE([j].[Reference],'$.TestSingle') AS real) AS [TestSingle], CAST(JSON_VALUE([j].[Reference],'$.TestTimeSpan') AS time) AS [TestTimeSpan], CAST(JSON_VALUE([j].[Reference],'$.TestUnsignedInt16') AS int) AS [TestUnsignedInt16], CAST(JSON_VALUE([j].[Reference],'$.TestUnsignedInt32') AS bigint) AS [TestUnsignedInt32], CAST(JSON_VALUE([j].[Reference],'$.TestUnsignedInt64') AS decimal(20,0)) AS [TestUnsignedInt64], CAST(JSON_VALUE([j].[Reference],'$.TestNullableInt32') AS int) AS [TestNullableInt32], CAST(JSON_VALUE([j].[Reference],'$.TestEnum') AS nvarchar(max)) AS [TestEnum], CAST(JSON_VALUE([j].[Reference],'$.TestEnumWithIntConverter') AS int) AS [TestEnumWithIntConverter], CAST(JSON_VALUE([j].[Reference],'$.TestNullableEnum') AS nvarchar(max)) AS [TestNullableEnum], CAST(JSON_VALUE([j].[Reference],'$.TestNullableEnumWithIntConverter') AS int) AS [TestNullableEnumWithIntConverter], CAST(JSON_VALUE([j].[Reference],'$.TestNullableEnumWithConverterThatHandlesNulls') AS nvarchar(max)) AS [TestNullableEnumWithConverterThatHandlesNulls] FROM [JsonEntitiesAllTypes] AS [j]"); } diff --git a/test/EFCore.SqlServer.FunctionalTests/Update/JsonUpdateSqlServerTest.cs b/test/EFCore.SqlServer.FunctionalTests/Update/JsonUpdateSqlServerTest.cs index 7236f95f5fc..f07d85653a9 100644 --- a/test/EFCore.SqlServer.FunctionalTests/Update/JsonUpdateSqlServerTest.cs +++ b/test/EFCore.SqlServer.FunctionalTests/Update/JsonUpdateSqlServerTest.cs @@ -16,7 +16,7 @@ public override async Task Add_element_to_json_collection_branch() await base.Add_element_to_json_collection_branch(); AssertSql( - @"@p0='[{""Date"":""2101-01-01T00:00:00"",""Enum"":""Two"",""Fraction"":10.1,""OwnedCollectionLeaf"":[{""SomethingSomething"":""e1_r_c1_c1""},{""SomethingSomething"":""e1_r_c1_c2""}],""OwnedReferenceLeaf"":{""SomethingSomething"":""e1_r_c1_r""}},{""Date"":""2102-01-01T00:00:00"",""Enum"":""Three"",""Fraction"":10.2,""OwnedCollectionLeaf"":[{""SomethingSomething"":""e1_r_c2_c1""},{""SomethingSomething"":""e1_r_c2_c2""}],""OwnedReferenceLeaf"":{""SomethingSomething"":""e1_r_c2_r""}},{""Date"":""2010-10-10T00:00:00"",""Enum"":""Three"",""Fraction"":42.42,""OwnedCollectionLeaf"":[{""SomethingSomething"":""ss1""},{""SomethingSomething"":""ss2""}],""OwnedReferenceLeaf"":{""SomethingSomething"":""ss3""}}]' (Nullable = false) (Size = 622) + @"@p0='[{""Date"":""2101-01-01T00:00:00"",""Enum"":""Two"",""Fraction"":10.1,""NullableEnum"":""One"",""OwnedCollectionLeaf"":[{""SomethingSomething"":""e1_r_c1_c1""},{""SomethingSomething"":""e1_r_c1_c2""}],""OwnedReferenceLeaf"":{""SomethingSomething"":""e1_r_c1_r""}},{""Date"":""2102-01-01T00:00:00"",""Enum"":""Three"",""Fraction"":10.2,""NullableEnum"":""Two"",""OwnedCollectionLeaf"":[{""SomethingSomething"":""e1_r_c2_c1""},{""SomethingSomething"":""e1_r_c2_c2""}],""OwnedReferenceLeaf"":{""SomethingSomething"":""e1_r_c2_r""}},{""Date"":""2010-10-10T00:00:00"",""Enum"":""Three"",""Fraction"":42.42,""NullableEnum"":null,""OwnedCollectionLeaf"":[{""SomethingSomething"":""ss1""},{""SomethingSomething"":""ss2""}],""OwnedReferenceLeaf"":{""SomethingSomething"":""ss3""}}]' (Nullable = false) (Size = 684) @p1='1' SET IMPLICIT_TRANSACTIONS OFF; @@ -24,8 +24,8 @@ public override async Task Add_element_to_json_collection_branch() UPDATE [JsonEntitiesBasic] SET [OwnedReferenceRoot] = JSON_MODIFY([OwnedReferenceRoot], 'strict $.OwnedCollectionBranch', JSON_QUERY(@p0)) OUTPUT 1 WHERE [Id] = @p1;", - // - @"SELECT TOP(2) [j].[Id], [j].[EntityBasicId], [j].[Name], JSON_QUERY([j].[OwnedCollectionRoot],'$'), JSON_QUERY([j].[OwnedReferenceRoot],'$') + // + @"SELECT TOP(2) [j].[Id], [j].[EntityBasicId], [j].[Name], JSON_QUERY([j].[OwnedCollectionRoot],'$'), JSON_QUERY([j].[OwnedReferenceRoot],'$') FROM [JsonEntitiesBasic] AS [j]"); } @@ -52,7 +52,7 @@ public override async Task Add_element_to_json_collection_on_derived() await base.Add_element_to_json_collection_on_derived(); AssertSql( - @"@p0='[{""Date"":""2221-01-01T00:00:00"",""Enum"":""Two"",""Fraction"":221.1,""OwnedCollectionLeaf"":[{""SomethingSomething"":""d2_r_c1""},{""SomethingSomething"":""d2_r_c2""}],""OwnedReferenceLeaf"":{""SomethingSomething"":""d2_r_r""}},{""Date"":""2222-01-01T00:00:00"",""Enum"":""Three"",""Fraction"":222.1,""OwnedCollectionLeaf"":[{""SomethingSomething"":""d2_r_c1""},{""SomethingSomething"":""d2_r_c2""}],""OwnedReferenceLeaf"":{""SomethingSomething"":""d2_r_r""}},{""Date"":""2010-10-10T00:00:00"",""Enum"":""Three"",""Fraction"":42.42,""OwnedCollectionLeaf"":[{""SomethingSomething"":""ss1""},{""SomethingSomething"":""ss2""}],""OwnedReferenceLeaf"":{""SomethingSomething"":""ss3""}}]' (Nullable = false) (Size = 606) + @"@p0='[{""Date"":""2221-01-01T00:00:00"",""Enum"":""Two"",""Fraction"":221.1,""NullableEnum"":""One"",""OwnedCollectionLeaf"":[{""SomethingSomething"":""d2_r_c1""},{""SomethingSomething"":""d2_r_c2""}],""OwnedReferenceLeaf"":{""SomethingSomething"":""d2_r_r""}},{""Date"":""2222-01-01T00:00:00"",""Enum"":""Three"",""Fraction"":222.1,""NullableEnum"":""Two"",""OwnedCollectionLeaf"":[{""SomethingSomething"":""d2_r_c1""},{""SomethingSomething"":""d2_r_c2""}],""OwnedReferenceLeaf"":{""SomethingSomething"":""d2_r_r""}},{""Date"":""2010-10-10T00:00:00"",""Enum"":""Three"",""Fraction"":42.42,""NullableEnum"":null,""OwnedCollectionLeaf"":[{""SomethingSomething"":""ss1""},{""SomethingSomething"":""ss2""}],""OwnedReferenceLeaf"":{""SomethingSomething"":""ss3""}}]' (Nullable = false) (Size = 668) @p1='2' SET IMPLICIT_TRANSACTIONS OFF; @@ -60,8 +60,8 @@ public override async Task Add_element_to_json_collection_on_derived() UPDATE [JsonEntitiesInheritance] SET [CollectionOnDerived] = @p0 OUTPUT 1 WHERE [Id] = @p1;", - // - @"SELECT TOP(2) [j].[Id], [j].[Discriminator], [j].[Name], [j].[Fraction], JSON_QUERY([j].[CollectionOnBase],'$'), JSON_QUERY([j].[ReferenceOnBase],'$'), JSON_QUERY([j].[CollectionOnDerived],'$'), JSON_QUERY([j].[ReferenceOnDerived],'$') + // + @"SELECT TOP(2) [j].[Id], [j].[Discriminator], [j].[Name], [j].[Fraction], JSON_QUERY([j].[CollectionOnBase],'$'), JSON_QUERY([j].[ReferenceOnBase],'$'), JSON_QUERY([j].[CollectionOnDerived],'$'), JSON_QUERY([j].[ReferenceOnDerived],'$') FROM [JsonEntitiesInheritance] AS [j] WHERE [j].[Discriminator] = N'JsonEntityInheritanceDerived'"); } @@ -71,7 +71,7 @@ public override async Task Add_element_to_json_collection_root() await base.Add_element_to_json_collection_root(); AssertSql( - @"@p0='[{""Name"":""e1_c1"",""Number"":11,""OwnedCollectionBranch"":[{""Date"":""2111-01-01T00:00:00"",""Enum"":""Two"",""Fraction"":11.1,""OwnedCollectionLeaf"":[{""SomethingSomething"":""e1_c1_c1_c1""},{""SomethingSomething"":""e1_c1_c1_c2""}],""OwnedReferenceLeaf"":{""SomethingSomething"":""e1_c1_c1_r""}},{""Date"":""2112-01-01T00:00:00"",""Enum"":""Three"",""Fraction"":11.2,""OwnedCollectionLeaf"":[{""SomethingSomething"":""e1_c1_c2_c1""},{""SomethingSomething"":""e1_c1_c2_c2""}],""OwnedReferenceLeaf"":{""SomethingSomething"":""e1_c1_c2_r""}}],""OwnedReferenceBranch"":{""Date"":""2110-01-01T00:00:00"",""Enum"":""One"",""Fraction"":11.0,""OwnedCollectionLeaf"":[{""SomethingSomething"":""e1_c1_r_c1""},{""SomethingSomething"":""e1_c1_r_c2""}],""OwnedReferenceLeaf"":{""SomethingSomething"":""e1_c1_r_r""}}},{""Name"":""e1_c2"",""Number"":12,""OwnedCollectionBranch"":[{""Date"":""2121-01-01T00:00:00"",""Enum"":""Two"",""Fraction"":12.1,""OwnedCollectionLeaf"":[{""SomethingSomething"":""e1_c2_c1_c1""},{""SomethingSomething"":""e1_c2_c1_c2""}],""OwnedReferenceLeaf"":{""SomethingSomething"":""e1_c2_c1_r""}},{""Date"":""2122-01-01T00:00:00"",""Enum"":""One"",""Fraction"":12.2,""OwnedCollectionLeaf"":[{""SomethingSomething"":""e1_c2_c2_c1""},{""SomethingSomething"":""e1_c2_c2_c2""}],""OwnedReferenceLeaf"":{""SomethingSomething"":""e1_c2_c2_r""}}],""OwnedReferenceBranch"":{""Date"":""2120-01-01T00:00:00"",""Enum"":""Three"",""Fraction"":12.0,""OwnedCollectionLeaf"":[{""SomethingSomething"":""e1_c2_r_c1""},{""SomethingSomething"":""e1_c2_r_c2""}],""OwnedReferenceLeaf"":{""SomethingSomething"":""e1_c2_r_r""}}},{""Name"":""new Name"",""Number"":142,""OwnedCollectionBranch"":[],""OwnedReferenceBranch"":{""Date"":""2010-10-10T00:00:00"",""Enum"":""Three"",""Fraction"":42.42,""OwnedCollectionLeaf"":[{""SomethingSomething"":""ss1""},{""SomethingSomething"":""ss2""}],""OwnedReferenceLeaf"":{""SomethingSomething"":""ss3""}}}]' (Nullable = false) (Size = 1723) + @"@p0='[{""Name"":""e1_c1"",""Number"":11,""OwnedCollectionBranch"":[{""Date"":""2111-01-01T00:00:00"",""Enum"":""Two"",""Fraction"":11.1,""NullableEnum"":""One"",""OwnedCollectionLeaf"":[{""SomethingSomething"":""e1_c1_c1_c1""},{""SomethingSomething"":""e1_c1_c1_c2""}],""OwnedReferenceLeaf"":{""SomethingSomething"":""e1_c1_c1_r""}},{""Date"":""2112-01-01T00:00:00"",""Enum"":""Three"",""Fraction"":11.2,""NullableEnum"":""Two"",""OwnedCollectionLeaf"":[{""SomethingSomething"":""e1_c1_c2_c1""},{""SomethingSomething"":""e1_c1_c2_c2""}],""OwnedReferenceLeaf"":{""SomethingSomething"":""e1_c1_c2_r""}}],""OwnedReferenceBranch"":{""Date"":""2110-01-01T00:00:00"",""Enum"":""One"",""Fraction"":11.0,""NullableEnum"":null,""OwnedCollectionLeaf"":[{""SomethingSomething"":""e1_c1_r_c1""},{""SomethingSomething"":""e1_c1_r_c2""}],""OwnedReferenceLeaf"":{""SomethingSomething"":""e1_c1_r_r""}}},{""Name"":""e1_c2"",""Number"":12,""OwnedCollectionBranch"":[{""Date"":""2121-01-01T00:00:00"",""Enum"":""Two"",""Fraction"":12.1,""NullableEnum"":""One"",""OwnedCollectionLeaf"":[{""SomethingSomething"":""e1_c2_c1_c1""},{""SomethingSomething"":""e1_c2_c1_c2""}],""OwnedReferenceLeaf"":{""SomethingSomething"":""e1_c2_c1_r""}},{""Date"":""2122-01-01T00:00:00"",""Enum"":""One"",""Fraction"":12.2,""NullableEnum"":null,""OwnedCollectionLeaf"":[{""SomethingSomething"":""e1_c2_c2_c1""},{""SomethingSomething"":""e1_c2_c2_c2""}],""OwnedReferenceLeaf"":{""SomethingSomething"":""e1_c2_c2_r""}}],""OwnedReferenceBranch"":{""Date"":""2120-01-01T00:00:00"",""Enum"":""Three"",""Fraction"":12.0,""NullableEnum"":""Two"",""OwnedCollectionLeaf"":[{""SomethingSomething"":""e1_c2_r_c1""},{""SomethingSomething"":""e1_c2_r_c2""}],""OwnedReferenceLeaf"":{""SomethingSomething"":""e1_c2_r_r""}}},{""Name"":""new Name"",""Number"":142,""OwnedCollectionBranch"":[],""OwnedReferenceBranch"":{""Date"":""2010-10-10T00:00:00"",""Enum"":""Three"",""Fraction"":42.42,""NullableEnum"":null,""OwnedCollectionLeaf"":[{""SomethingSomething"":""ss1""},{""SomethingSomething"":""ss2""}],""OwnedReferenceLeaf"":{""SomethingSomething"":""ss3""}}}]' (Nullable = false) (Size = 1867) @p1='1' SET IMPLICIT_TRANSACTIONS OFF; @@ -79,8 +79,8 @@ public override async Task Add_element_to_json_collection_root() UPDATE [JsonEntitiesBasic] SET [OwnedCollectionRoot] = @p0 OUTPUT 1 WHERE [Id] = @p1;", - // - @"SELECT TOP(2) [j].[Id], [j].[EntityBasicId], [j].[Name], JSON_QUERY([j].[OwnedCollectionRoot],'$'), JSON_QUERY([j].[OwnedReferenceRoot],'$') + // + @"SELECT TOP(2) [j].[Id], [j].[EntityBasicId], [j].[Name], JSON_QUERY([j].[OwnedCollectionRoot],'$'), JSON_QUERY([j].[OwnedReferenceRoot],'$') FROM [JsonEntitiesBasic] AS [j]"); } @@ -89,7 +89,7 @@ public override async Task Add_entity_with_json() await base.Add_entity_with_json(); AssertSql( - @"@p0='{""Name"":""RootName"",""Number"":42,""OwnedCollectionBranch"":[],""OwnedReferenceBranch"":{""Date"":""2010-10-10T00:00:00"",""Enum"":""Three"",""Fraction"":42.42,""OwnedCollectionLeaf"":[{""SomethingSomething"":""ss1""},{""SomethingSomething"":""ss2""}],""OwnedReferenceLeaf"":{""SomethingSomething"":""ss3""}}}' (Nullable = false) (Size = 276) + @"@p0='{""Name"":""RootName"",""Number"":42,""OwnedCollectionBranch"":[],""OwnedReferenceBranch"":{""Date"":""2010-10-10T00:00:00"",""Enum"":""Three"",""Fraction"":42.42,""NullableEnum"":null,""OwnedCollectionLeaf"":[{""SomethingSomething"":""ss1""},{""SomethingSomething"":""ss2""}],""OwnedReferenceLeaf"":{""SomethingSomething"":""ss3""}}}' (Nullable = false) (Size = 296) @p1='2' @p2=NULL (DbType = Int32) @p3='NewEntity' (Size = 4000) @@ -98,8 +98,8 @@ public override async Task Add_entity_with_json() SET NOCOUNT ON; INSERT INTO [JsonEntitiesBasic] ([OwnedReferenceRoot], [Id], [EntityBasicId], [Name]) VALUES (@p0, @p1, @p2, @p3);", - // - @"SELECT [j].[Id], [j].[EntityBasicId], [j].[Name], JSON_QUERY([j].[OwnedCollectionRoot],'$'), JSON_QUERY([j].[OwnedReferenceRoot],'$') + // + @"SELECT [j].[Id], [j].[EntityBasicId], [j].[Name], JSON_QUERY([j].[OwnedCollectionRoot],'$'), JSON_QUERY([j].[OwnedReferenceRoot],'$') FROM [JsonEntitiesBasic] AS [j]"); } @@ -126,7 +126,7 @@ public override async Task Add_json_reference_root() await base.Add_json_reference_root(); AssertSql( - @"@p0='{""Name"":""RootName"",""Number"":42,""OwnedCollectionBranch"":[],""OwnedReferenceBranch"":{""Date"":""2010-10-10T00:00:00"",""Enum"":""Three"",""Fraction"":42.42,""OwnedCollectionLeaf"":[{""SomethingSomething"":""ss1""},{""SomethingSomething"":""ss2""}],""OwnedReferenceLeaf"":{""SomethingSomething"":""ss3""}}}' (Nullable = false) (Size = 276) + @"@p0='{""Name"":""RootName"",""Number"":42,""OwnedCollectionBranch"":[],""OwnedReferenceBranch"":{""Date"":""2010-10-10T00:00:00"",""Enum"":""Three"",""Fraction"":42.42,""NullableEnum"":null,""OwnedCollectionLeaf"":[{""SomethingSomething"":""ss1""},{""SomethingSomething"":""ss2""}],""OwnedReferenceLeaf"":{""SomethingSomething"":""ss3""}}}' (Nullable = false) (Size = 296) @p1='1' SET IMPLICIT_TRANSACTIONS OFF; @@ -134,8 +134,8 @@ public override async Task Add_json_reference_root() UPDATE [JsonEntitiesBasic] SET [OwnedReferenceRoot] = @p0 OUTPUT 1 WHERE [Id] = @p1;", - // - @"SELECT TOP(2) [j].[Id], [j].[EntityBasicId], [j].[Name], JSON_QUERY([j].[OwnedCollectionRoot],'$'), JSON_QUERY([j].[OwnedReferenceRoot],'$') + // + @"SELECT TOP(2) [j].[Id], [j].[EntityBasicId], [j].[Name], JSON_QUERY([j].[OwnedCollectionRoot],'$'), JSON_QUERY([j].[OwnedReferenceRoot],'$') FROM [JsonEntitiesBasic] AS [j]"); } @@ -287,8 +287,8 @@ public override async Task Edit_element_in_json_multiple_levels_partial_update() await base.Edit_element_in_json_multiple_levels_partial_update(); AssertSql( - @"@p0='[{""Date"":""2111-01-01T00:00:00"",""Enum"":""Two"",""Fraction"":11.1,""OwnedCollectionLeaf"":[{""SomethingSomething"":""...and another""},{""SomethingSomething"":""e1_c1_c1_c2""}],""OwnedReferenceLeaf"":{""SomethingSomething"":""e1_c1_c1_r""}},{""Date"":""2112-01-01T00:00:00"",""Enum"":""Three"",""Fraction"":11.2,""OwnedCollectionLeaf"":[{""SomethingSomething"":""yet another change""},{""SomethingSomething"":""and another""}],""OwnedReferenceLeaf"":{""SomethingSomething"":""e1_c1_c2_r""}}]' (Nullable = false) (Size = 443) -@p1='{""Name"":""edit"",""Number"":10,""OwnedCollectionBranch"":[{""Date"":""2101-01-01T00:00:00"",""Enum"":""Two"",""Fraction"":10.1,""OwnedCollectionLeaf"":[{""SomethingSomething"":""e1_r_c1_c1""},{""SomethingSomething"":""e1_r_c1_c2""}],""OwnedReferenceLeaf"":{""SomethingSomething"":""e1_r_c1_r""}},{""Date"":""2102-01-01T00:00:00"",""Enum"":""Three"",""Fraction"":10.2,""OwnedCollectionLeaf"":[{""SomethingSomething"":""e1_r_c2_c1""},{""SomethingSomething"":""e1_r_c2_c2""}],""OwnedReferenceLeaf"":{""SomethingSomething"":""e1_r_c2_r""}}],""OwnedReferenceBranch"":{""Date"":""2111-11-11T00:00:00"",""Enum"":""One"",""Fraction"":10.0,""OwnedCollectionLeaf"":[{""SomethingSomething"":""e1_r_r_c1""},{""SomethingSomething"":""e1_r_r_c2""}],""OwnedReferenceLeaf"":{""SomethingSomething"":""e1_r_r_r""}}}' (Nullable = false) (Size = 711) + @"@p0='[{""Date"":""2111-01-01T00:00:00"",""Enum"":""Two"",""Fraction"":11.1,""NullableEnum"":""One"",""OwnedCollectionLeaf"":[{""SomethingSomething"":""...and another""},{""SomethingSomething"":""e1_c1_c1_c2""}],""OwnedReferenceLeaf"":{""SomethingSomething"":""e1_c1_c1_r""}},{""Date"":""2112-01-01T00:00:00"",""Enum"":""Three"",""Fraction"":11.2,""NullableEnum"":""Two"",""OwnedCollectionLeaf"":[{""SomethingSomething"":""yet another change""},{""SomethingSomething"":""and another""}],""OwnedReferenceLeaf"":{""SomethingSomething"":""e1_c1_c2_r""}}]' (Nullable = false) (Size = 485) +@p1='{""Name"":""edit"",""Number"":10,""OwnedCollectionBranch"":[{""Date"":""2101-01-01T00:00:00"",""Enum"":""Two"",""Fraction"":10.1,""NullableEnum"":""One"",""OwnedCollectionLeaf"":[{""SomethingSomething"":""e1_r_c1_c1""},{""SomethingSomething"":""e1_r_c1_c2""}],""OwnedReferenceLeaf"":{""SomethingSomething"":""e1_r_c1_r""}},{""Date"":""2102-01-01T00:00:00"",""Enum"":""Three"",""Fraction"":10.2,""NullableEnum"":""Two"",""OwnedCollectionLeaf"":[{""SomethingSomething"":""e1_r_c2_c1""},{""SomethingSomething"":""e1_r_c2_c2""}],""OwnedReferenceLeaf"":{""SomethingSomething"":""e1_r_c2_r""}}],""OwnedReferenceBranch"":{""Date"":""2111-11-11T00:00:00"",""Enum"":""One"",""Fraction"":10.0,""NullableEnum"":null,""OwnedCollectionLeaf"":[{""SomethingSomething"":""e1_r_r_c1""},{""SomethingSomething"":""e1_r_r_c2""}],""OwnedReferenceLeaf"":{""SomethingSomething"":""e1_r_r_r""}}}' (Nullable = false) (Size = 773) @p2='1' SET IMPLICIT_TRANSACTIONS OFF; @@ -296,8 +296,8 @@ public override async Task Edit_element_in_json_multiple_levels_partial_update() UPDATE [JsonEntitiesBasic] SET [OwnedCollectionRoot] = JSON_MODIFY([OwnedCollectionRoot], 'strict $[0].OwnedCollectionBranch', JSON_QUERY(@p0)), [OwnedReferenceRoot] = @p1 OUTPUT 1 WHERE [Id] = @p2;", - // - @"SELECT TOP(2) [j].[Id], [j].[EntityBasicId], [j].[Name], JSON_QUERY([j].[OwnedCollectionRoot],'$'), JSON_QUERY([j].[OwnedReferenceRoot],'$') + // + @"SELECT TOP(2) [j].[Id], [j].[EntityBasicId], [j].[Name], JSON_QUERY([j].[OwnedCollectionRoot],'$'), JSON_QUERY([j].[OwnedReferenceRoot],'$') FROM [JsonEntitiesBasic] AS [j]"); } @@ -306,7 +306,7 @@ public override async Task Edit_element_in_json_branch_collection_and_add_elemen await base.Edit_element_in_json_branch_collection_and_add_element_to_the_same_collection(); AssertSql( - @"@p0='[{""Date"":""2101-01-01T00:00:00"",""Enum"":""Two"",""Fraction"":4321.3,""OwnedCollectionLeaf"":[{""SomethingSomething"":""e1_r_c1_c1""},{""SomethingSomething"":""e1_r_c1_c2""}],""OwnedReferenceLeaf"":{""SomethingSomething"":""e1_r_c1_r""}},{""Date"":""2102-01-01T00:00:00"",""Enum"":""Three"",""Fraction"":10.2,""OwnedCollectionLeaf"":[{""SomethingSomething"":""e1_r_c2_c1""},{""SomethingSomething"":""e1_r_c2_c2""}],""OwnedReferenceLeaf"":{""SomethingSomething"":""e1_r_c2_r""}},{""Date"":""2222-11-11T00:00:00"",""Enum"":""Three"",""Fraction"":45.32,""OwnedCollectionLeaf"":[],""OwnedReferenceLeaf"":{""SomethingSomething"":""cc""}}]' (Nullable = false) (Size = 566) + @"@p0='[{""Date"":""2101-01-01T00:00:00"",""Enum"":""Two"",""Fraction"":4321.3,""NullableEnum"":""One"",""OwnedCollectionLeaf"":[{""SomethingSomething"":""e1_r_c1_c1""},{""SomethingSomething"":""e1_r_c1_c2""}],""OwnedReferenceLeaf"":{""SomethingSomething"":""e1_r_c1_r""}},{""Date"":""2102-01-01T00:00:00"",""Enum"":""Three"",""Fraction"":10.2,""NullableEnum"":""Two"",""OwnedCollectionLeaf"":[{""SomethingSomething"":""e1_r_c2_c1""},{""SomethingSomething"":""e1_r_c2_c2""}],""OwnedReferenceLeaf"":{""SomethingSomething"":""e1_r_c2_r""}},{""Date"":""2222-11-11T00:00:00"",""Enum"":""Three"",""Fraction"":45.32,""NullableEnum"":null,""OwnedCollectionLeaf"":[],""OwnedReferenceLeaf"":{""SomethingSomething"":""cc""}}]' (Nullable = false) (Size = 628) @p1='1' SET IMPLICIT_TRANSACTIONS OFF; @@ -314,8 +314,8 @@ public override async Task Edit_element_in_json_branch_collection_and_add_elemen UPDATE [JsonEntitiesBasic] SET [OwnedReferenceRoot] = JSON_MODIFY([OwnedReferenceRoot], 'strict $.OwnedCollectionBranch', JSON_QUERY(@p0)) OUTPUT 1 WHERE [Id] = @p1;", - // - @"SELECT TOP(2) [j].[Id], [j].[EntityBasicId], [j].[Name], JSON_QUERY([j].[OwnedCollectionRoot],'$'), JSON_QUERY([j].[OwnedReferenceRoot],'$') + // + @"SELECT TOP(2) [j].[Id], [j].[EntityBasicId], [j].[Name], JSON_QUERY([j].[OwnedCollectionRoot],'$'), JSON_QUERY([j].[OwnedReferenceRoot],'$') FROM [JsonEntitiesBasic] AS [j]"); } @@ -342,7 +342,7 @@ public override async Task Edit_two_elements_in_the_same_json_collection_at_the_ await base.Edit_two_elements_in_the_same_json_collection_at_the_root(); AssertSql( - @"@p0='[{""Name"":""edit1"",""Number"":11,""OwnedCollectionBranch"":[{""Date"":""2111-01-01T00:00:00"",""Enum"":""Two"",""Fraction"":11.1,""OwnedCollectionLeaf"":[{""SomethingSomething"":""e1_c1_c1_c1""},{""SomethingSomething"":""e1_c1_c1_c2""}],""OwnedReferenceLeaf"":{""SomethingSomething"":""e1_c1_c1_r""}},{""Date"":""2112-01-01T00:00:00"",""Enum"":""Three"",""Fraction"":11.2,""OwnedCollectionLeaf"":[{""SomethingSomething"":""e1_c1_c2_c1""},{""SomethingSomething"":""e1_c1_c2_c2""}],""OwnedReferenceLeaf"":{""SomethingSomething"":""e1_c1_c2_r""}}],""OwnedReferenceBranch"":{""Date"":""2110-01-01T00:00:00"",""Enum"":""One"",""Fraction"":11.0,""OwnedCollectionLeaf"":[{""SomethingSomething"":""e1_c1_r_c1""},{""SomethingSomething"":""e1_c1_r_c2""}],""OwnedReferenceLeaf"":{""SomethingSomething"":""e1_c1_r_r""}}},{""Name"":""edit2"",""Number"":12,""OwnedCollectionBranch"":[{""Date"":""2121-01-01T00:00:00"",""Enum"":""Two"",""Fraction"":12.1,""OwnedCollectionLeaf"":[{""SomethingSomething"":""e1_c2_c1_c1""},{""SomethingSomething"":""e1_c2_c1_c2""}],""OwnedReferenceLeaf"":{""SomethingSomething"":""e1_c2_c1_r""}},{""Date"":""2122-01-01T00:00:00"",""Enum"":""One"",""Fraction"":12.2,""OwnedCollectionLeaf"":[{""SomethingSomething"":""e1_c2_c2_c1""},{""SomethingSomething"":""e1_c2_c2_c2""}],""OwnedReferenceLeaf"":{""SomethingSomething"":""e1_c2_c2_r""}}],""OwnedReferenceBranch"":{""Date"":""2120-01-01T00:00:00"",""Enum"":""Three"",""Fraction"":12.0,""OwnedCollectionLeaf"":[{""SomethingSomething"":""e1_c2_r_c1""},{""SomethingSomething"":""e1_c2_r_c2""}],""OwnedReferenceLeaf"":{""SomethingSomething"":""e1_c2_r_r""}}}]' (Nullable = false) (Size = 1445) + @"@p0='[{""Name"":""edit1"",""Number"":11,""OwnedCollectionBranch"":[{""Date"":""2111-01-01T00:00:00"",""Enum"":""Two"",""Fraction"":11.1,""NullableEnum"":""One"",""OwnedCollectionLeaf"":[{""SomethingSomething"":""e1_c1_c1_c1""},{""SomethingSomething"":""e1_c1_c1_c2""}],""OwnedReferenceLeaf"":{""SomethingSomething"":""e1_c1_c1_r""}},{""Date"":""2112-01-01T00:00:00"",""Enum"":""Three"",""Fraction"":11.2,""NullableEnum"":""Two"",""OwnedCollectionLeaf"":[{""SomethingSomething"":""e1_c1_c2_c1""},{""SomethingSomething"":""e1_c1_c2_c2""}],""OwnedReferenceLeaf"":{""SomethingSomething"":""e1_c1_c2_r""}}],""OwnedReferenceBranch"":{""Date"":""2110-01-01T00:00:00"",""Enum"":""One"",""Fraction"":11.0,""NullableEnum"":null,""OwnedCollectionLeaf"":[{""SomethingSomething"":""e1_c1_r_c1""},{""SomethingSomething"":""e1_c1_r_c2""}],""OwnedReferenceLeaf"":{""SomethingSomething"":""e1_c1_r_r""}}},{""Name"":""edit2"",""Number"":12,""OwnedCollectionBranch"":[{""Date"":""2121-01-01T00:00:00"",""Enum"":""Two"",""Fraction"":12.1,""NullableEnum"":""One"",""OwnedCollectionLeaf"":[{""SomethingSomething"":""e1_c2_c1_c1""},{""SomethingSomething"":""e1_c2_c1_c2""}],""OwnedReferenceLeaf"":{""SomethingSomething"":""e1_c2_c1_r""}},{""Date"":""2122-01-01T00:00:00"",""Enum"":""One"",""Fraction"":12.2,""NullableEnum"":null,""OwnedCollectionLeaf"":[{""SomethingSomething"":""e1_c2_c2_c1""},{""SomethingSomething"":""e1_c2_c2_c2""}],""OwnedReferenceLeaf"":{""SomethingSomething"":""e1_c2_c2_r""}}],""OwnedReferenceBranch"":{""Date"":""2120-01-01T00:00:00"",""Enum"":""Three"",""Fraction"":12.0,""NullableEnum"":""Two"",""OwnedCollectionLeaf"":[{""SomethingSomething"":""e1_c2_r_c1""},{""SomethingSomething"":""e1_c2_r_c2""}],""OwnedReferenceLeaf"":{""SomethingSomething"":""e1_c2_r_r""}}}]' (Nullable = false) (Size = 1569) @p1='1' SET IMPLICIT_TRANSACTIONS OFF; @@ -350,8 +350,8 @@ public override async Task Edit_two_elements_in_the_same_json_collection_at_the_ UPDATE [JsonEntitiesBasic] SET [OwnedCollectionRoot] = @p0 OUTPUT 1 WHERE [Id] = @p1;", - // - @"SELECT TOP(2) [j].[Id], [j].[EntityBasicId], [j].[Name], JSON_QUERY([j].[OwnedCollectionRoot],'$'), JSON_QUERY([j].[OwnedReferenceRoot],'$') + // + @"SELECT TOP(2) [j].[Id], [j].[EntityBasicId], [j].[Name], JSON_QUERY([j].[OwnedCollectionRoot],'$'), JSON_QUERY([j].[OwnedReferenceRoot],'$') FROM [JsonEntitiesBasic] AS [j]"); } @@ -360,7 +360,7 @@ public override async Task Edit_collection_element_and_reference_at_once() await base.Edit_collection_element_and_reference_at_once(); AssertSql( - @"@p0='{""Date"":""2102-01-01T00:00:00"",""Enum"":""Three"",""Fraction"":10.2,""OwnedCollectionLeaf"":[{""SomethingSomething"":""edit1""},{""SomethingSomething"":""e1_r_c2_c2""}],""OwnedReferenceLeaf"":{""SomethingSomething"":""edit2""}}' (Nullable = false) (Size = 204) + @"@p0='{""Date"":""2102-01-01T00:00:00"",""Enum"":""Three"",""Fraction"":10.2,""NullableEnum"":""Two"",""OwnedCollectionLeaf"":[{""SomethingSomething"":""edit1""},{""SomethingSomething"":""e1_r_c2_c2""}],""OwnedReferenceLeaf"":{""SomethingSomething"":""edit2""}}' (Nullable = false) (Size = 225) @p1='1' SET IMPLICIT_TRANSACTIONS OFF; @@ -368,8 +368,8 @@ public override async Task Edit_collection_element_and_reference_at_once() UPDATE [JsonEntitiesBasic] SET [OwnedReferenceRoot] = JSON_MODIFY([OwnedReferenceRoot], 'strict $.OwnedCollectionBranch[1]', JSON_QUERY(@p0)) OUTPUT 1 WHERE [Id] = @p1;", - // - @"SELECT TOP(2) [j].[Id], [j].[EntityBasicId], [j].[Name], JSON_QUERY([j].[OwnedCollectionRoot],'$'), JSON_QUERY([j].[OwnedReferenceRoot],'$') + // + @"SELECT TOP(2) [j].[Id], [j].[EntityBasicId], [j].[Name], JSON_QUERY([j].[OwnedCollectionRoot],'$'), JSON_QUERY([j].[OwnedReferenceRoot],'$') FROM [JsonEntitiesBasic] AS [j]"); } @@ -425,9 +425,10 @@ public override async Task Edit_single_property_bool() UPDATE [JsonEntitiesAllTypes] SET [Collection] = JSON_MODIFY([Collection], 'strict $[0].TestBoolean', CAST(JSON_VALUE(@p0, '$[0]') AS bit)), [Reference] = JSON_MODIFY([Reference], 'strict $.TestBoolean', CAST(JSON_VALUE(@p1, '$[0]') AS bit)) OUTPUT 1 WHERE [Id] = @p2;", - // - @"SELECT TOP(2) [j].[Id], JSON_QUERY([j].[Collection],'$'), JSON_QUERY([j].[Reference],'$') -FROM [JsonEntitiesAllTypes] AS [j]"); + // + @"SELECT TOP(2) [j].[Id], JSON_QUERY([j].[Collection],'$'), JSON_QUERY([j].[Reference],'$') +FROM [JsonEntitiesAllTypes] AS [j] +WHERE [j].[Id] = 1"); } public override async Task Edit_single_property_byte() @@ -444,9 +445,10 @@ public override async Task Edit_single_property_byte() UPDATE [JsonEntitiesAllTypes] SET [Collection] = JSON_MODIFY([Collection], 'strict $[0].TestByte', CAST(JSON_VALUE(@p0, '$[0]') AS tinyint)), [Reference] = JSON_MODIFY([Reference], 'strict $.TestByte', CAST(JSON_VALUE(@p1, '$[0]') AS tinyint)) OUTPUT 1 WHERE [Id] = @p2;", - // - @"SELECT TOP(2) [j].[Id], JSON_QUERY([j].[Collection],'$'), JSON_QUERY([j].[Reference],'$') -FROM [JsonEntitiesAllTypes] AS [j]"); + // + @"SELECT TOP(2) [j].[Id], JSON_QUERY([j].[Collection],'$'), JSON_QUERY([j].[Reference],'$') +FROM [JsonEntitiesAllTypes] AS [j] +WHERE [j].[Id] = 1"); } public override async Task Edit_single_property_char() @@ -462,9 +464,10 @@ public override async Task Edit_single_property_char() UPDATE [JsonEntitiesAllTypes] SET [Reference] = JSON_MODIFY([Reference], 'strict $.TestCharacter', CAST(JSON_VALUE(@p0, '$[0]') AS nvarchar(1))) OUTPUT 1 WHERE [Id] = @p1;", - // - @"SELECT TOP(2) [j].[Id], JSON_QUERY([j].[Collection],'$'), JSON_QUERY([j].[Reference],'$') -FROM [JsonEntitiesAllTypes] AS [j]"); + // + @"SELECT TOP(2) [j].[Id], JSON_QUERY([j].[Collection],'$'), JSON_QUERY([j].[Reference],'$') +FROM [JsonEntitiesAllTypes] AS [j] +WHERE [j].[Id] = 1"); } public override async Task Edit_single_property_datetime() @@ -481,9 +484,10 @@ public override async Task Edit_single_property_datetime() UPDATE [JsonEntitiesAllTypes] SET [Collection] = JSON_MODIFY([Collection], 'strict $[0].TestDateTime', JSON_VALUE(@p0, '$[0]')), [Reference] = JSON_MODIFY([Reference], 'strict $.TestDateTime', JSON_VALUE(@p1, '$[0]')) OUTPUT 1 WHERE [Id] = @p2;", - // - @"SELECT TOP(2) [j].[Id], JSON_QUERY([j].[Collection],'$'), JSON_QUERY([j].[Reference],'$') -FROM [JsonEntitiesAllTypes] AS [j]"); + // + @"SELECT TOP(2) [j].[Id], JSON_QUERY([j].[Collection],'$'), JSON_QUERY([j].[Reference],'$') +FROM [JsonEntitiesAllTypes] AS [j] +WHERE [j].[Id] = 1"); } public override async Task Edit_single_property_datetimeoffset() @@ -500,9 +504,10 @@ public override async Task Edit_single_property_datetimeoffset() UPDATE [JsonEntitiesAllTypes] SET [Collection] = JSON_MODIFY([Collection], 'strict $[0].TestDateTimeOffset', JSON_VALUE(@p0, '$[0]')), [Reference] = JSON_MODIFY([Reference], 'strict $.TestDateTimeOffset', JSON_VALUE(@p1, '$[0]')) OUTPUT 1 WHERE [Id] = @p2;", - // - @"SELECT TOP(2) [j].[Id], JSON_QUERY([j].[Collection],'$'), JSON_QUERY([j].[Reference],'$') -FROM [JsonEntitiesAllTypes] AS [j]"); + // + @"SELECT TOP(2) [j].[Id], JSON_QUERY([j].[Collection],'$'), JSON_QUERY([j].[Reference],'$') +FROM [JsonEntitiesAllTypes] AS [j] +WHERE [j].[Id] = 1"); } public override async Task Edit_single_property_decimal() @@ -519,9 +524,10 @@ public override async Task Edit_single_property_decimal() UPDATE [JsonEntitiesAllTypes] SET [Collection] = JSON_MODIFY([Collection], 'strict $[0].TestDecimal', CAST(JSON_VALUE(@p0, '$[0]') AS decimal(18,3))), [Reference] = JSON_MODIFY([Reference], 'strict $.TestDecimal', CAST(JSON_VALUE(@p1, '$[0]') AS decimal(18,3))) OUTPUT 1 WHERE [Id] = @p2;", - // - @"SELECT TOP(2) [j].[Id], JSON_QUERY([j].[Collection],'$'), JSON_QUERY([j].[Reference],'$') -FROM [JsonEntitiesAllTypes] AS [j]"); + // + @"SELECT TOP(2) [j].[Id], JSON_QUERY([j].[Collection],'$'), JSON_QUERY([j].[Reference],'$') +FROM [JsonEntitiesAllTypes] AS [j] +WHERE [j].[Id] = 1"); } public override async Task Edit_single_property_double() @@ -538,9 +544,10 @@ public override async Task Edit_single_property_double() UPDATE [JsonEntitiesAllTypes] SET [Collection] = JSON_MODIFY([Collection], 'strict $[0].TestDouble', CAST(JSON_VALUE(@p0, '$[0]') AS float)), [Reference] = JSON_MODIFY([Reference], 'strict $.TestDouble', CAST(JSON_VALUE(@p1, '$[0]') AS float)) OUTPUT 1 WHERE [Id] = @p2;", - // - @"SELECT TOP(2) [j].[Id], JSON_QUERY([j].[Collection],'$'), JSON_QUERY([j].[Reference],'$') -FROM [JsonEntitiesAllTypes] AS [j]"); + // + @"SELECT TOP(2) [j].[Id], JSON_QUERY([j].[Collection],'$'), JSON_QUERY([j].[Reference],'$') +FROM [JsonEntitiesAllTypes] AS [j] +WHERE [j].[Id] = 1"); } public override async Task Edit_single_property_guid() @@ -557,9 +564,10 @@ public override async Task Edit_single_property_guid() UPDATE [JsonEntitiesAllTypes] SET [Collection] = JSON_MODIFY([Collection], 'strict $[0].TestGuid', JSON_VALUE(@p0, '$[0]')), [Reference] = JSON_MODIFY([Reference], 'strict $.TestGuid', JSON_VALUE(@p1, '$[0]')) OUTPUT 1 WHERE [Id] = @p2;", - // - @"SELECT TOP(2) [j].[Id], JSON_QUERY([j].[Collection],'$'), JSON_QUERY([j].[Reference],'$') -FROM [JsonEntitiesAllTypes] AS [j]"); + // + @"SELECT TOP(2) [j].[Id], JSON_QUERY([j].[Collection],'$'), JSON_QUERY([j].[Reference],'$') +FROM [JsonEntitiesAllTypes] AS [j] +WHERE [j].[Id] = 1"); } public override async Task Edit_single_property_int16() @@ -576,9 +584,10 @@ public override async Task Edit_single_property_int16() UPDATE [JsonEntitiesAllTypes] SET [Collection] = JSON_MODIFY([Collection], 'strict $[0].TestInt16', CAST(JSON_VALUE(@p0, '$[0]') AS smallint)), [Reference] = JSON_MODIFY([Reference], 'strict $.TestInt16', CAST(JSON_VALUE(@p1, '$[0]') AS smallint)) OUTPUT 1 WHERE [Id] = @p2;", - // - @"SELECT TOP(2) [j].[Id], JSON_QUERY([j].[Collection],'$'), JSON_QUERY([j].[Reference],'$') -FROM [JsonEntitiesAllTypes] AS [j]"); + // + @"SELECT TOP(2) [j].[Id], JSON_QUERY([j].[Collection],'$'), JSON_QUERY([j].[Reference],'$') +FROM [JsonEntitiesAllTypes] AS [j] +WHERE [j].[Id] = 1"); } public override async Task Edit_single_property_int32() @@ -595,9 +604,10 @@ public override async Task Edit_single_property_int32() UPDATE [JsonEntitiesAllTypes] SET [Collection] = JSON_MODIFY([Collection], 'strict $[0].TestInt32', CAST(JSON_VALUE(@p0, '$[0]') AS int)), [Reference] = JSON_MODIFY([Reference], 'strict $.TestInt32', CAST(JSON_VALUE(@p1, '$[0]') AS int)) OUTPUT 1 WHERE [Id] = @p2;", - // - @"SELECT TOP(2) [j].[Id], JSON_QUERY([j].[Collection],'$'), JSON_QUERY([j].[Reference],'$') -FROM [JsonEntitiesAllTypes] AS [j]"); + // + @"SELECT TOP(2) [j].[Id], JSON_QUERY([j].[Collection],'$'), JSON_QUERY([j].[Reference],'$') +FROM [JsonEntitiesAllTypes] AS [j] +WHERE [j].[Id] = 1"); } public override async Task Edit_single_property_int64() @@ -614,9 +624,10 @@ public override async Task Edit_single_property_int64() UPDATE [JsonEntitiesAllTypes] SET [Collection] = JSON_MODIFY([Collection], 'strict $[0].TestInt64', CAST(JSON_VALUE(@p0, '$[0]') AS bigint)), [Reference] = JSON_MODIFY([Reference], 'strict $.TestInt64', CAST(JSON_VALUE(@p1, '$[0]') AS bigint)) OUTPUT 1 WHERE [Id] = @p2;", - // - @"SELECT TOP(2) [j].[Id], JSON_QUERY([j].[Collection],'$'), JSON_QUERY([j].[Reference],'$') -FROM [JsonEntitiesAllTypes] AS [j]"); + // + @"SELECT TOP(2) [j].[Id], JSON_QUERY([j].[Collection],'$'), JSON_QUERY([j].[Reference],'$') +FROM [JsonEntitiesAllTypes] AS [j] +WHERE [j].[Id] = 1"); } public override async Task Edit_single_property_signed_byte() @@ -633,9 +644,10 @@ public override async Task Edit_single_property_signed_byte() UPDATE [JsonEntitiesAllTypes] SET [Collection] = JSON_MODIFY([Collection], 'strict $[0].TestSignedByte', CAST(JSON_VALUE(@p0, '$[0]') AS smallint)), [Reference] = JSON_MODIFY([Reference], 'strict $.TestSignedByte', CAST(JSON_VALUE(@p1, '$[0]') AS smallint)) OUTPUT 1 WHERE [Id] = @p2;", - // - @"SELECT TOP(2) [j].[Id], JSON_QUERY([j].[Collection],'$'), JSON_QUERY([j].[Reference],'$') -FROM [JsonEntitiesAllTypes] AS [j]"); + // + @"SELECT TOP(2) [j].[Id], JSON_QUERY([j].[Collection],'$'), JSON_QUERY([j].[Reference],'$') +FROM [JsonEntitiesAllTypes] AS [j] +WHERE [j].[Id] = 1"); } public override async Task Edit_single_property_single() @@ -652,9 +664,10 @@ public override async Task Edit_single_property_single() UPDATE [JsonEntitiesAllTypes] SET [Collection] = JSON_MODIFY([Collection], 'strict $[0].TestSingle', CAST(JSON_VALUE(@p0, '$[0]') AS real)), [Reference] = JSON_MODIFY([Reference], 'strict $.TestSingle', CAST(JSON_VALUE(@p1, '$[0]') AS real)) OUTPUT 1 WHERE [Id] = @p2;", - // - @"SELECT TOP(2) [j].[Id], JSON_QUERY([j].[Collection],'$'), JSON_QUERY([j].[Reference],'$') -FROM [JsonEntitiesAllTypes] AS [j]"); + // + @"SELECT TOP(2) [j].[Id], JSON_QUERY([j].[Collection],'$'), JSON_QUERY([j].[Reference],'$') +FROM [JsonEntitiesAllTypes] AS [j] +WHERE [j].[Id] = 1"); } public override async Task Edit_single_property_timespan() @@ -671,9 +684,10 @@ public override async Task Edit_single_property_timespan() UPDATE [JsonEntitiesAllTypes] SET [Collection] = JSON_MODIFY([Collection], 'strict $[0].TestTimeSpan', JSON_VALUE(@p0, '$[0]')), [Reference] = JSON_MODIFY([Reference], 'strict $.TestTimeSpan', JSON_VALUE(@p1, '$[0]')) OUTPUT 1 WHERE [Id] = @p2;", - // - @"SELECT TOP(2) [j].[Id], JSON_QUERY([j].[Collection],'$'), JSON_QUERY([j].[Reference],'$') -FROM [JsonEntitiesAllTypes] AS [j]"); + // + @"SELECT TOP(2) [j].[Id], JSON_QUERY([j].[Collection],'$'), JSON_QUERY([j].[Reference],'$') +FROM [JsonEntitiesAllTypes] AS [j] +WHERE [j].[Id] = 1"); } public override async Task Edit_single_property_uint16() @@ -690,9 +704,10 @@ public override async Task Edit_single_property_uint16() UPDATE [JsonEntitiesAllTypes] SET [Collection] = JSON_MODIFY([Collection], 'strict $[0].TestUnsignedInt16', CAST(JSON_VALUE(@p0, '$[0]') AS int)), [Reference] = JSON_MODIFY([Reference], 'strict $.TestUnsignedInt16', CAST(JSON_VALUE(@p1, '$[0]') AS int)) OUTPUT 1 WHERE [Id] = @p2;", - // - @"SELECT TOP(2) [j].[Id], JSON_QUERY([j].[Collection],'$'), JSON_QUERY([j].[Reference],'$') -FROM [JsonEntitiesAllTypes] AS [j]"); + // + @"SELECT TOP(2) [j].[Id], JSON_QUERY([j].[Collection],'$'), JSON_QUERY([j].[Reference],'$') +FROM [JsonEntitiesAllTypes] AS [j] +WHERE [j].[Id] = 1"); } public override async Task Edit_single_property_uint32() @@ -709,9 +724,10 @@ public override async Task Edit_single_property_uint32() UPDATE [JsonEntitiesAllTypes] SET [Collection] = JSON_MODIFY([Collection], 'strict $[0].TestUnsignedInt32', CAST(JSON_VALUE(@p0, '$[0]') AS bigint)), [Reference] = JSON_MODIFY([Reference], 'strict $.TestUnsignedInt32', CAST(JSON_VALUE(@p1, '$[0]') AS bigint)) OUTPUT 1 WHERE [Id] = @p2;", - // - @"SELECT TOP(2) [j].[Id], JSON_QUERY([j].[Collection],'$'), JSON_QUERY([j].[Reference],'$') -FROM [JsonEntitiesAllTypes] AS [j]"); + // + @"SELECT TOP(2) [j].[Id], JSON_QUERY([j].[Collection],'$'), JSON_QUERY([j].[Reference],'$') +FROM [JsonEntitiesAllTypes] AS [j] +WHERE [j].[Id] = 1"); } public override async Task Edit_single_property_uint64() @@ -728,9 +744,210 @@ public override async Task Edit_single_property_uint64() UPDATE [JsonEntitiesAllTypes] SET [Collection] = JSON_MODIFY([Collection], 'strict $[0].TestUnsignedInt64', CAST(JSON_VALUE(@p0, '$[0]') AS decimal(20,0))), [Reference] = JSON_MODIFY([Reference], 'strict $.TestUnsignedInt64', CAST(JSON_VALUE(@p1, '$[0]') AS decimal(20,0))) OUTPUT 1 WHERE [Id] = @p2;", - // - @"SELECT TOP(2) [j].[Id], JSON_QUERY([j].[Collection],'$'), JSON_QUERY([j].[Reference],'$') -FROM [JsonEntitiesAllTypes] AS [j]"); + // + @"SELECT TOP(2) [j].[Id], JSON_QUERY([j].[Collection],'$'), JSON_QUERY([j].[Reference],'$') +FROM [JsonEntitiesAllTypes] AS [j] +WHERE [j].[Id] = 1"); + } + + public override async Task Edit_single_property_nullable_int32() + { + await base.Edit_single_property_nullable_int32(); + + AssertSql( + @"@p0='[122354]' (Nullable = false) (Size = 8) +@p1='[64528]' (Nullable = false) (Size = 7) +@p2='1' + +SET IMPLICIT_TRANSACTIONS OFF; +SET NOCOUNT ON; +UPDATE [JsonEntitiesAllTypes] SET [Collection] = JSON_MODIFY([Collection], 'strict $[0].TestNullableInt32', CAST(JSON_VALUE(@p0, '$[0]') AS int)), [Reference] = JSON_MODIFY([Reference], 'strict $.TestNullableInt32', CAST(JSON_VALUE(@p1, '$[0]') AS int)) +OUTPUT 1 +WHERE [Id] = @p2;", + // + @"SELECT TOP(2) [j].[Id], JSON_QUERY([j].[Collection],'$'), JSON_QUERY([j].[Reference],'$') +FROM [JsonEntitiesAllTypes] AS [j] +WHERE [j].[Id] = 1"); + } + + public override async Task Edit_single_property_nullable_int32_set_to_null() + { + await base.Edit_single_property_nullable_int32_set_to_null(); + + AssertSql( + @"@p0='[null]' (Nullable = false) (Size = 6) +@p1='[null]' (Nullable = false) (Size = 6) +@p2='1' + +SET IMPLICIT_TRANSACTIONS OFF; +SET NOCOUNT ON; +UPDATE [JsonEntitiesAllTypes] SET [Collection] = JSON_MODIFY([Collection], 'strict $[0].TestNullableInt32', CAST(JSON_VALUE(@p0, '$[0]') AS int)), [Reference] = JSON_MODIFY([Reference], 'strict $.TestNullableInt32', CAST(JSON_VALUE(@p1, '$[0]') AS int)) +OUTPUT 1 +WHERE [Id] = @p2;", + // + @"SELECT TOP(2) [j].[Id], JSON_QUERY([j].[Collection],'$'), JSON_QUERY([j].[Reference],'$') +FROM [JsonEntitiesAllTypes] AS [j] +WHERE [j].[Id] = 1"); + } + + public override async Task Edit_single_property_enum() + { + await base.Edit_single_property_enum(); + + AssertSql( + @"@p0='[""Three""]' (Nullable = false) (Size = 9) +@p1='[""Three""]' (Nullable = false) (Size = 9) +@p2='1' + +SET IMPLICIT_TRANSACTIONS OFF; +SET NOCOUNT ON; +UPDATE [JsonEntitiesAllTypes] SET [Collection] = JSON_MODIFY([Collection], 'strict $[0].TestEnum', JSON_VALUE(@p0, '$[0]')), [Reference] = JSON_MODIFY([Reference], 'strict $.TestEnum', JSON_VALUE(@p1, '$[0]')) +OUTPUT 1 +WHERE [Id] = @p2;", + // + @"SELECT TOP(2) [j].[Id], JSON_QUERY([j].[Collection],'$'), JSON_QUERY([j].[Reference],'$') +FROM [JsonEntitiesAllTypes] AS [j] +WHERE [j].[Id] = 1"); + } + + public override async Task Edit_single_property_enum_with_int_converter() + { + await base.Edit_single_property_enum_with_int_converter(); + + AssertSql( + @"@p0='[""Three""]' (Nullable = false) (Size = 9) +@p1='[""Three""]' (Nullable = false) (Size = 9) +@p2='1' + +SET IMPLICIT_TRANSACTIONS OFF; +SET NOCOUNT ON; +UPDATE [JsonEntitiesAllTypes] SET [Collection] = JSON_MODIFY([Collection], 'strict $[0].TestEnumWithIntConverter', JSON_VALUE(@p0, '$[0]')), [Reference] = JSON_MODIFY([Reference], 'strict $.TestEnumWithIntConverter', JSON_VALUE(@p1, '$[0]')) +OUTPUT 1 +WHERE [Id] = @p2;", + // + @"SELECT TOP(2) [j].[Id], JSON_QUERY([j].[Collection],'$'), JSON_QUERY([j].[Reference],'$') +FROM [JsonEntitiesAllTypes] AS [j] +WHERE [j].[Id] = 1"); + } + + public override async Task Edit_single_property_nullable_enum() + { + await base.Edit_single_property_nullable_enum(); + + AssertSql( + @"@p0='[""Three""]' (Nullable = false) (Size = 9) +@p1='[""Three""]' (Nullable = false) (Size = 9) +@p2='1' + +SET IMPLICIT_TRANSACTIONS OFF; +SET NOCOUNT ON; +UPDATE [JsonEntitiesAllTypes] SET [Collection] = JSON_MODIFY([Collection], 'strict $[0].TestEnum', JSON_VALUE(@p0, '$[0]')), [Reference] = JSON_MODIFY([Reference], 'strict $.TestEnum', JSON_VALUE(@p1, '$[0]')) +OUTPUT 1 +WHERE [Id] = @p2;", + // + @"SELECT TOP(2) [j].[Id], JSON_QUERY([j].[Collection],'$'), JSON_QUERY([j].[Reference],'$') +FROM [JsonEntitiesAllTypes] AS [j] +WHERE [j].[Id] = 1"); + } + + public override async Task Edit_single_property_nullable_enum_set_to_null() + { + await base.Edit_single_property_nullable_enum_set_to_null(); + + AssertSql( + @"@p0='[null]' (Nullable = false) (Size = 6) +@p1='[null]' (Nullable = false) (Size = 6) +@p2='1' + +SET IMPLICIT_TRANSACTIONS OFF; +SET NOCOUNT ON; +UPDATE [JsonEntitiesAllTypes] SET [Collection] = JSON_MODIFY([Collection], 'strict $[0].TestNullableEnum', JSON_VALUE(@p0, '$[0]')), [Reference] = JSON_MODIFY([Reference], 'strict $.TestNullableEnum', JSON_VALUE(@p1, '$[0]')) +OUTPUT 1 +WHERE [Id] = @p2;", + // + @"SELECT TOP(2) [j].[Id], JSON_QUERY([j].[Collection],'$'), JSON_QUERY([j].[Reference],'$') +FROM [JsonEntitiesAllTypes] AS [j] +WHERE [j].[Id] = 1"); + } + + public override async Task Edit_single_property_nullable_enum_with_int_converter() + { + await base.Edit_single_property_nullable_enum_with_int_converter(); + + AssertSql( + @"@p0='[""One""]' (Nullable = false) (Size = 7) +@p1='[""Three""]' (Nullable = false) (Size = 9) +@p2='1' + +SET IMPLICIT_TRANSACTIONS OFF; +SET NOCOUNT ON; +UPDATE [JsonEntitiesAllTypes] SET [Collection] = JSON_MODIFY([Collection], 'strict $[0].TestNullableEnumWithIntConverter', JSON_VALUE(@p0, '$[0]')), [Reference] = JSON_MODIFY([Reference], 'strict $.TestNullableEnumWithIntConverter', JSON_VALUE(@p1, '$[0]')) +OUTPUT 1 +WHERE [Id] = @p2;", + // + @"SELECT TOP(2) [j].[Id], JSON_QUERY([j].[Collection],'$'), JSON_QUERY([j].[Reference],'$') +FROM [JsonEntitiesAllTypes] AS [j] +WHERE [j].[Id] = 1"); + } + + public override async Task Edit_single_property_nullable_enum_with_int_converter_set_to_null() + { + await base.Edit_single_property_nullable_enum_with_int_converter_set_to_null(); + + AssertSql( + @"@p0='[null]' (Nullable = false) (Size = 6) +@p1='[null]' (Nullable = false) (Size = 6) +@p2='1' + +SET IMPLICIT_TRANSACTIONS OFF; +SET NOCOUNT ON; +UPDATE [JsonEntitiesAllTypes] SET [Collection] = JSON_MODIFY([Collection], 'strict $[0].TestNullableEnumWithIntConverter', JSON_VALUE(@p0, '$[0]')), [Reference] = JSON_MODIFY([Reference], 'strict $.TestNullableEnumWithIntConverter', JSON_VALUE(@p1, '$[0]')) +OUTPUT 1 +WHERE [Id] = @p2;", + // + @"SELECT TOP(2) [j].[Id], JSON_QUERY([j].[Collection],'$'), JSON_QUERY([j].[Reference],'$') +FROM [JsonEntitiesAllTypes] AS [j] +WHERE [j].[Id] = 1"); + } + + public override async Task Edit_single_property_nullable_enum_with_converter_that_handles_nulls() + { + await base.Edit_single_property_nullable_enum_with_converter_that_handles_nulls(); + + AssertSql( + @"@p0='[""Three""]' (Nullable = false) (Size = 9) +@p1='[""One""]' (Nullable = false) (Size = 7) +@p2='1' + +SET IMPLICIT_TRANSACTIONS OFF; +SET NOCOUNT ON; +UPDATE [JsonEntitiesAllTypes] SET [Collection] = JSON_MODIFY([Collection], 'strict $[0].TestNullableEnumWithConverterThatHandlesNulls', JSON_VALUE(@p0, '$[0]')), [Reference] = JSON_MODIFY([Reference], 'strict $.TestNullableEnumWithConverterThatHandlesNulls', JSON_VALUE(@p1, '$[0]')) +OUTPUT 1 +WHERE [Id] = @p2;", + // + @"SELECT TOP(2) [j].[Id], JSON_QUERY([j].[Collection],'$'), JSON_QUERY([j].[Reference],'$') +FROM [JsonEntitiesAllTypes] AS [j] +WHERE [j].[Id] = 1"); + } + + public override async Task Edit_single_property_nullable_enum_with_converter_that_handles_nulls_set_to_null() + { + await base.Edit_single_property_nullable_enum_with_converter_that_handles_nulls_set_to_null(); + + AssertSql( + @"@p0='[null]' (Nullable = false) (Size = 6) +@p1='[null]' (Nullable = false) (Size = 6) +@p2='1' + +SET IMPLICIT_TRANSACTIONS OFF; +SET NOCOUNT ON; +UPDATE [JsonEntitiesAllTypes] SET [Collection] = JSON_MODIFY([Collection], 'strict $[0].TestNullableEnumWithConverterThatHandlesNulls', JSON_VALUE(@p0, '$[0]')), [Reference] = JSON_MODIFY([Reference], 'strict $.TestNullableEnumWithConverterThatHandlesNulls', JSON_VALUE(@p1, '$[0]')) +OUTPUT 1 +WHERE [Id] = @p2;", + // + @"SELECT TOP(2) [j].[Id], JSON_QUERY([j].[Collection],'$'), JSON_QUERY([j].[Reference],'$') +FROM [JsonEntitiesAllTypes] AS [j] +WHERE [j].[Id] = 1"); } public override async Task Edit_two_properties_on_same_entity_updates_the_entire_entity() @@ -738,8 +955,8 @@ public override async Task Edit_two_properties_on_same_entity_updates_the_entire await base.Edit_two_properties_on_same_entity_updates_the_entire_entity(); AssertSql( - @"@p0='{""TestBoolean"":false,""TestByte"":25,""TestCharacter"":""h"",""TestDateTime"":""2100-11-11T12:34:56"",""TestDateTimeOffset"":""2200-11-11T12:34:56-05:00"",""TestDecimal"":-123450.01,""TestDouble"":-1.2345,""TestGuid"":""00000000-0000-0000-0000-000000000000"",""TestInt16"":-12,""TestInt32"":32,""TestInt64"":64,""TestSignedByte"":-18,""TestSingle"":-1.4,""TestTimeSpan"":""06:05:04.0030000"",""TestUnsignedInt16"":12,""TestUnsignedInt32"":12345,""TestUnsignedInt64"":1234567867}' (Nullable = false) (Size = 436) -@p1='{""TestBoolean"":true,""TestByte"":255,""TestCharacter"":""a"",""TestDateTime"":""2000-01-01T12:34:56"",""TestDateTimeOffset"":""2000-01-01T12:34:56-08:00"",""TestDecimal"":-1234567890.01,""TestDouble"":-1.23456789,""TestGuid"":""12345678-1234-4321-7777-987654321000"",""TestInt16"":-1234,""TestInt32"":32,""TestInt64"":64,""TestSignedByte"":-128,""TestSingle"":-1.234,""TestTimeSpan"":""10:09:08.0070000"",""TestUnsignedInt16"":1234,""TestUnsignedInt32"":1234565789,""TestUnsignedInt64"":1234567890123456789}' (Nullable = false) (Size = 465) + @"@p0='{""TestBoolean"":false,""TestByte"":25,""TestCharacter"":""h"",""TestDateTime"":""2100-11-11T12:34:56"",""TestDateTimeOffset"":""2200-11-11T12:34:56-05:00"",""TestDecimal"":-123450.01,""TestDouble"":-1.2345,""TestEnum"":""One"",""TestEnumWithIntConverter"":""Two"",""TestGuid"":""00000000-0000-0000-0000-000000000000"",""TestInt16"":-12,""TestInt32"":32,""TestInt64"":64,""TestNullableEnum"":""One"",""TestNullableEnumWithConverterThatHandlesNulls"":""Two"",""TestNullableEnumWithIntConverter"":""Three"",""TestNullableInt32"":90,""TestSignedByte"":-18,""TestSingle"":-1.4,""TestTimeSpan"":""06:05:04.0030000"",""TestUnsignedInt16"":12,""TestUnsignedInt32"":12345,""TestUnsignedInt64"":1234567867}' (Nullable = false) (Size = 631) +@p1='{""TestBoolean"":true,""TestByte"":255,""TestCharacter"":""a"",""TestDateTime"":""2000-01-01T12:34:56"",""TestDateTimeOffset"":""2000-01-01T12:34:56-08:00"",""TestDecimal"":-1234567890.01,""TestDouble"":-1.23456789,""TestEnum"":""One"",""TestEnumWithIntConverter"":""Two"",""TestGuid"":""12345678-1234-4321-7777-987654321000"",""TestInt16"":-1234,""TestInt32"":32,""TestInt64"":64,""TestNullableEnum"":""One"",""TestNullableEnumWithConverterThatHandlesNulls"":""Three"",""TestNullableEnumWithIntConverter"":""Two"",""TestNullableInt32"":78,""TestSignedByte"":-128,""TestSingle"":-1.234,""TestTimeSpan"":""10:09:08.0070000"",""TestUnsignedInt16"":1234,""TestUnsignedInt32"":1234565789,""TestUnsignedInt64"":1234567890123456789}' (Nullable = false) (Size = 660) @p2='1' SET IMPLICIT_TRANSACTIONS OFF; @@ -747,9 +964,10 @@ public override async Task Edit_two_properties_on_same_entity_updates_the_entire UPDATE [JsonEntitiesAllTypes] SET [Collection] = JSON_MODIFY([Collection], 'strict $[0]', JSON_QUERY(@p0)), [Reference] = @p1 OUTPUT 1 WHERE [Id] = @p2;", - // - @"SELECT TOP(2) [j].[Id], JSON_QUERY([j].[Collection],'$'), JSON_QUERY([j].[Reference],'$') -FROM [JsonEntitiesAllTypes] AS [j]"); + // + @"SELECT TOP(2) [j].[Id], JSON_QUERY([j].[Collection],'$'), JSON_QUERY([j].[Reference],'$') +FROM [JsonEntitiesAllTypes] AS [j] +WHERE [j].[Id] = 1"); } public override async Task Edit_a_scalar_property_and_reference_navigation_on_the_same_entity() @@ -757,7 +975,7 @@ public override async Task Edit_a_scalar_property_and_reference_navigation_on_th await base.Edit_a_scalar_property_and_reference_navigation_on_the_same_entity(); AssertSql( - @"@p0='{""Date"":""2100-01-01T00:00:00"",""Enum"":""One"",""Fraction"":523.532,""OwnedCollectionLeaf"":[{""SomethingSomething"":""e1_r_r_c1""},{""SomethingSomething"":""e1_r_r_c2""}],""OwnedReferenceLeaf"":{""SomethingSomething"":""edit""}}' (Nullable = false) (Size = 207) + @"@p0='{""Date"":""2100-01-01T00:00:00"",""Enum"":""One"",""Fraction"":523.532,""NullableEnum"":null,""OwnedCollectionLeaf"":[{""SomethingSomething"":""e1_r_r_c1""},{""SomethingSomething"":""e1_r_r_c2""}],""OwnedReferenceLeaf"":{""SomethingSomething"":""edit""}}' (Nullable = false) (Size = 227) @p1='1' SET IMPLICIT_TRANSACTIONS OFF; @@ -765,8 +983,8 @@ public override async Task Edit_a_scalar_property_and_reference_navigation_on_th UPDATE [JsonEntitiesBasic] SET [OwnedReferenceRoot] = JSON_MODIFY([OwnedReferenceRoot], 'strict $.OwnedReferenceBranch', JSON_QUERY(@p0)) OUTPUT 1 WHERE [Id] = @p1;", - // - @"SELECT TOP(2) [j].[Id], [j].[EntityBasicId], [j].[Name], JSON_QUERY([j].[OwnedCollectionRoot],'$'), JSON_QUERY([j].[OwnedReferenceRoot],'$') + // + @"SELECT TOP(2) [j].[Id], [j].[EntityBasicId], [j].[Name], JSON_QUERY([j].[OwnedCollectionRoot],'$'), JSON_QUERY([j].[OwnedReferenceRoot],'$') FROM [JsonEntitiesBasic] AS [j]"); } @@ -775,7 +993,7 @@ public override async Task Edit_a_scalar_property_and_collection_navigation_on_t await base.Edit_a_scalar_property_and_collection_navigation_on_the_same_entity(); AssertSql( - @"@p0='{""Date"":""2100-01-01T00:00:00"",""Enum"":""One"",""Fraction"":523.532,""OwnedCollectionLeaf"":[{""SomethingSomething"":""edit""}],""OwnedReferenceLeaf"":{""SomethingSomething"":""e1_r_r_r""}}' (Nullable = false) (Size = 171) + @"@p0='{""Date"":""2100-01-01T00:00:00"",""Enum"":""One"",""Fraction"":523.532,""NullableEnum"":null,""OwnedCollectionLeaf"":[{""SomethingSomething"":""edit""}],""OwnedReferenceLeaf"":{""SomethingSomething"":""e1_r_r_r""}}' (Nullable = false) (Size = 191) @p1='1' SET IMPLICIT_TRANSACTIONS OFF; @@ -783,8 +1001,8 @@ public override async Task Edit_a_scalar_property_and_collection_navigation_on_t UPDATE [JsonEntitiesBasic] SET [OwnedReferenceRoot] = JSON_MODIFY([OwnedReferenceRoot], 'strict $.OwnedReferenceBranch', JSON_QUERY(@p0)) OUTPUT 1 WHERE [Id] = @p1;", - // - @"SELECT TOP(2) [j].[Id], [j].[EntityBasicId], [j].[Name], JSON_QUERY([j].[OwnedCollectionRoot],'$'), JSON_QUERY([j].[OwnedReferenceRoot],'$') + // + @"SELECT TOP(2) [j].[Id], [j].[EntityBasicId], [j].[Name], JSON_QUERY([j].[OwnedCollectionRoot],'$'), JSON_QUERY([j].[OwnedReferenceRoot],'$') FROM [JsonEntitiesBasic] AS [j]"); } @@ -793,7 +1011,7 @@ public override async Task Edit_a_scalar_property_and_another_property_behind_re await base.Edit_a_scalar_property_and_another_property_behind_reference_navigation_on_the_same_entity(); AssertSql( - @"@p0='{""Date"":""2100-01-01T00:00:00"",""Enum"":""One"",""Fraction"":523.532,""OwnedCollectionLeaf"":[{""SomethingSomething"":""e1_r_r_c1""},{""SomethingSomething"":""e1_r_r_c2""}],""OwnedReferenceLeaf"":{""SomethingSomething"":""edit""}}' (Nullable = false) (Size = 207) + @"@p0='{""Date"":""2100-01-01T00:00:00"",""Enum"":""One"",""Fraction"":523.532,""NullableEnum"":null,""OwnedCollectionLeaf"":[{""SomethingSomething"":""e1_r_r_c1""},{""SomethingSomething"":""e1_r_r_c2""}],""OwnedReferenceLeaf"":{""SomethingSomething"":""edit""}}' (Nullable = false) (Size = 227) @p1='1' SET IMPLICIT_TRANSACTIONS OFF; @@ -801,8 +1019,8 @@ public override async Task Edit_a_scalar_property_and_another_property_behind_re UPDATE [JsonEntitiesBasic] SET [OwnedReferenceRoot] = JSON_MODIFY([OwnedReferenceRoot], 'strict $.OwnedReferenceBranch', JSON_QUERY(@p0)) OUTPUT 1 WHERE [Id] = @p1;", - // - @"SELECT TOP(2) [j].[Id], [j].[EntityBasicId], [j].[Name], JSON_QUERY([j].[OwnedCollectionRoot],'$'), JSON_QUERY([j].[OwnedReferenceRoot],'$') + // + @"SELECT TOP(2) [j].[Id], [j].[EntityBasicId], [j].[Name], JSON_QUERY([j].[OwnedCollectionRoot],'$'), JSON_QUERY([j].[OwnedReferenceRoot],'$') FROM [JsonEntitiesBasic] AS [j]"); } diff --git a/test/EFCore.Sqlite.FunctionalTests/SqliteComplianceTest.cs b/test/EFCore.Sqlite.FunctionalTests/SqliteComplianceTest.cs index 0aba24228e3..70b6b4ee80f 100644 --- a/test/EFCore.Sqlite.FunctionalTests/SqliteComplianceTest.cs +++ b/test/EFCore.Sqlite.FunctionalTests/SqliteComplianceTest.cs @@ -10,6 +10,7 @@ public class SqliteComplianceTest : RelationalComplianceTestBase typeof(FromSqlSprocQueryTestBase<>), typeof(JsonQueryTestBase<>), typeof(JsonUpdateTestBase<>), + typeof(JsonQueryAdHocTestBase), typeof(SqlExecutorTestBase<>), typeof(UdfDbFunctionTestBase<>), typeof(TPCRelationshipsQueryTestBase<>), // internal class is added