diff --git a/src/EFCore.Sqlite.Core/Storage/Internal/SqliteByteArrayTypeMapping.cs b/src/EFCore.Sqlite.Core/Storage/Internal/SqliteByteArrayTypeMapping.cs
index e2bccc551a7..0c223a56263 100644
--- a/src/EFCore.Sqlite.Core/Storage/Internal/SqliteByteArrayTypeMapping.cs
+++ b/src/EFCore.Sqlite.Core/Storage/Internal/SqliteByteArrayTypeMapping.cs
@@ -35,20 +35,28 @@ public SqliteByteArrayTypeMapping(string storeType, DbType? dbType = System.Data
typeof(byte[]),
jsonValueReaderWriter: SqliteJsonByteArrayReaderWriter.Instance),
storeType,
- dbType: dbType))
+ dbType: dbType),
+ false)
{
}
+ private SqliteByteArrayTypeMapping(
+ RelationalTypeMappingParameters parameters,
+ bool isJsonColumn)
+ : base(parameters)
+ {
+ _isJsonColumn = isJsonColumn;
+ }
+
+ private readonly bool _isJsonColumn;
+
///
/// This is an internal API that supports the Entity Framework Core infrastructure and not subject to
/// the same compatibility standards as public APIs. It may be changed or removed without notice in
/// any release. You should only use it directly in your code with extreme caution and knowing that
/// doing so can result in application failures when updating to a new Entity Framework Core release.
///
- protected SqliteByteArrayTypeMapping(RelationalTypeMappingParameters parameters)
- : base(parameters)
- {
- }
+
///
/// Creates a copy of this mapping.
@@ -56,5 +64,21 @@ protected SqliteByteArrayTypeMapping(RelationalTypeMappingParameters parameters)
/// The parameters for this mapping.
/// The newly created mapping.
protected override RelationalTypeMapping Clone(RelationalTypeMappingParameters parameters)
- => new SqliteByteArrayTypeMapping(parameters);
+ => new SqliteByteArrayTypeMapping(parameters, _isJsonColumn);
+
+ internal SqliteByteArrayTypeMapping WithJsonColumn()
+ => new(Parameters, true);
+
+ ///
+ /// Configures the parameter, setting the to
+ /// when the mapping is for a JSON column.
+ ///
+ /// The parameter to be configured.
+ protected override void ConfigureParameter(DbParameter parameter)
+ {
+ if (_isJsonColumn && parameter is Data.Sqlite.SqliteParameter sqliteParameter)
+ {
+ sqliteParameter.SqliteType = Data.Sqlite.SqliteType.Text;
+ }
+ }
}
diff --git a/src/EFCore.Sqlite.Core/Storage/Internal/SqliteTimeOnlyTypeMapping.cs b/src/EFCore.Sqlite.Core/Storage/Internal/SqliteTimeOnlyTypeMapping.cs
index f10b7d6d398..993dafbd51f 100644
--- a/src/EFCore.Sqlite.Core/Storage/Internal/SqliteTimeOnlyTypeMapping.cs
+++ b/src/EFCore.Sqlite.Core/Storage/Internal/SqliteTimeOnlyTypeMapping.cs
@@ -2,6 +2,7 @@
// The .NET Foundation licenses this file to you under the MIT license.
using System.Data;
+using Microsoft.EntityFrameworkCore.Sqlite.Storage.Json.Internal;
using Microsoft.EntityFrameworkCore.Storage.Json;
namespace Microsoft.EntityFrameworkCore.Sqlite.Storage.Internal;
@@ -33,7 +34,7 @@ public SqliteTimeOnlyTypeMapping(
DbType? dbType = System.Data.DbType.Time)
: base(
new RelationalTypeMappingParameters(
- new CoreTypeMappingParameters(typeof(TimeOnly), jsonValueReaderWriter: JsonTimeOnlyReaderWriter.Instance),
+ new CoreTypeMappingParameters(typeof(TimeOnly), jsonValueReaderWriter: SqliteJsonTimeOnlyReaderWriter.Instance),
storeType,
dbType: dbType))
{
diff --git a/src/EFCore.Sqlite.Core/Storage/Internal/SqliteTypeMappingSource.cs b/src/EFCore.Sqlite.Core/Storage/Internal/SqliteTypeMappingSource.cs
index d28b9373970..e971c45d499 100644
--- a/src/EFCore.Sqlite.Core/Storage/Internal/SqliteTypeMappingSource.cs
+++ b/src/EFCore.Sqlite.Core/Storage/Internal/SqliteTypeMappingSource.cs
@@ -131,6 +131,28 @@ public static bool IsSpatialiteType(string columnType)
: mapping;
}
+ ///
+ /// This is an internal API that supports the Entity Framework Core infrastructure and not subject to
+ /// the same compatibility standards as public APIs. It may be changed or removed without notice in
+ /// any release. You should only use it directly in your code with extreme caution and knowing that
+ /// doing so can result in application failures when updating to a new Entity Framework Core release.
+ ///
+ ///
+ /// Finds the type mapping for a given property. This method is overridden to special-case byte[]
+ /// properties inside JSON columns, returning a mapping that works with Base64-encoded strings.
+ ///
+ /// The property for which mapping is to be found.
+ /// The type mapping, or if none was found.
+ public override RelationalTypeMapping? FindMapping(IProperty property)
+ {
+ var mapping = base.FindMapping(property);
+ if (mapping is SqliteByteArrayTypeMapping byteArrayMapping && property.DeclaringType.IsMappedToJson())
+ {
+ return byteArrayMapping.WithJsonColumn();
+ }
+ return mapping;
+ }
+
private RelationalTypeMapping? FindRawMapping(RelationalTypeMappingInfo mappingInfo)
{
var clrType = mappingInfo.ClrType;
diff --git a/src/EFCore.Sqlite.Core/Storage/Json/Internal/SqliteJsonTimeOnlyReaderWriter.cs b/src/EFCore.Sqlite.Core/Storage/Json/Internal/SqliteJsonTimeOnlyReaderWriter.cs
new file mode 100644
index 00000000000..c163d4017a3
--- /dev/null
+++ b/src/EFCore.Sqlite.Core/Storage/Json/Internal/SqliteJsonTimeOnlyReaderWriter.cs
@@ -0,0 +1,58 @@
+// Licensed to the .NET Foundation under one or more agreements.
+// The .NET Foundation licenses this file to you under the MIT license.
+
+using System.Globalization;
+using System.Text.Json;
+using Microsoft.EntityFrameworkCore.Storage.Json;
+
+namespace Microsoft.EntityFrameworkCore.Sqlite.Storage.Json.Internal;
+
+///
+/// The Sqlite-specific JsonValueReaderWrite for byte[]. Generates the SQLite representation (e.g. X'0102') rather than base64, in order
+/// to match our SQLite non-JSON representation.
+///
+///
+/// This is an internal API that supports the Entity Framework Core infrastructure and not subject to
+/// the same compatibility standards as public APIs. It may be changed or removed without notice in
+/// any release. You should only use it directly in your code with extreme caution and knowing that
+/// doing so can result in application failures when updating to a new Entity Framework Core release.
+///
+public sealed class SqliteJsonTimeOnlyReaderWriter : JsonValueReaderWriter
+{
+ private static readonly PropertyInfo InstanceProperty = typeof(SqliteJsonTimeOnlyReaderWriter).GetProperty(nameof(Instance))!;
+
+ ///
+ /// This is an internal API that supports the Entity Framework Core infrastructure and not subject to
+ /// the same compatibility standards as public APIs. It may be changed or removed without notice in
+ /// any release. You should only use it directly in your code with extreme caution and knowing that
+ /// doing so can result in application failures when updating to a new Entity Framework Core release.
+ ///
+ public static SqliteJsonTimeOnlyReaderWriter Instance { get; } = new();
+
+ private SqliteJsonTimeOnlyReaderWriter()
+ {
+ }
+
+ ///
+ /// This is an internal API that supports the Entity Framework Core infrastructure and not subject to
+ /// the same compatibility standards as public APIs. It may be changed or removed without notice in
+ /// any release. You should only use it directly in your code with extreme caution and knowing that
+ /// doing so can result in application failures when updating to a new Entity Framework Core release.
+ ///
+ public override TimeOnly FromJsonTyped(ref Utf8JsonReaderManager manager, object? existingObject = null)
+ => TimeOnly.Parse(manager.CurrentReader.GetString()!);
+
+ ///
+ /// This is an internal API that supports the Entity Framework Core infrastructure and not subject to
+ /// the same compatibility standards as public APIs. It may be changed or removed without notice in
+ /// any release. You should only use it directly in your code with extreme caution and knowing that
+ /// doing so can result in application failures when updating to a new Entity Framework Core release.
+ ///
+ public override void ToJsonTyped(Utf8JsonWriter writer, TimeOnly value)
+ => writer.WriteStringValue(value.Ticks % TimeSpan.TicksPerSecond == 0 ? string.Format(CultureInfo.InvariantCulture, @"{0:HH\:mm\:ss}", value)
+ : value.ToString("o"));
+
+ ///
+ public override Expression ConstructorExpression
+ => Expression.Property(null, InstanceProperty);
+}
diff --git a/src/Microsoft.Data.Sqlite.Core/SqliteValueBinder.cs b/src/Microsoft.Data.Sqlite.Core/SqliteValueBinder.cs
index 35fca9e4a44..549f8a18820 100644
--- a/src/Microsoft.Data.Sqlite.Core/SqliteValueBinder.cs
+++ b/src/Microsoft.Data.Sqlite.Core/SqliteValueBinder.cs
@@ -61,8 +61,17 @@ public virtual void Bind()
}
else if (type == typeof(byte[]))
{
+ // In Sqlite json columns parameter binding for byte[] resulted in a blob being bound to whereas the column is a text column thats why this conversion is needed.
var value1 = (byte[])value;
- BindBlob(value1);
+ if (sqliteType == SqliteType.Text)
+ {
+ var value = ToHexString(value1);
+ BindText(value);
+ }
+ else
+ {
+ BindBlob(value1);
+ }
}
else if (type == typeof(char))
{
@@ -313,4 +322,24 @@ private static double GetTotalDays(int hour, int minute, int second, int millise
return iJD / 86400000.0;
}
+
+ private static string ToHexString(byte[] bytes)
+ {
+
+ char[] hexChars = new char[bytes.Length * 2];
+
+ for (int i = 0; i < bytes.Length; i++)
+ {
+ byte b = bytes[i];
+
+ int highNibble = (b >> 4);
+ int lowNibble = (b & 0x0F);
+
+ hexChars[i * 2] = (char)(highNibble < 10 ? highNibble + '0' : highNibble + 'A' - 10);
+ hexChars[i * 2 + 1] = (char)(lowNibble < 10 ? lowNibble + '0' : lowNibble + 'A' - 10);
+ }
+
+ return new string(hexChars);
+ }
+
}
diff --git a/test/EFCore.Sqlite.FunctionalTests/JsonTypesSqliteTest.cs b/test/EFCore.Sqlite.FunctionalTests/JsonTypesSqliteTest.cs
index 08a6e784d2b..c0ba0231233 100644
--- a/test/EFCore.Sqlite.FunctionalTests/JsonTypesSqliteTest.cs
+++ b/test/EFCore.Sqlite.FunctionalTests/JsonTypesSqliteTest.cs
@@ -184,6 +184,51 @@ public override Task Can_read_write_collection_of_nullable_GUID_JSON_values(stri
=> base.Can_read_write_collection_of_nullable_GUID_JSON_values(
"""{"Prop":["00000000-0000-0000-0000-000000000000",null,"8C44242F-8E3F-4A20-8BE8-98C7C1AADEBD","FFFFFFFF-FFFF-FFFF-FFFF-FFFFFFFFFFFF"]}""");
+ public override Task Can_read_write_TimeOnly_JSON_values(string value, string json)
+ => base.Can_read_write_TimeOnly_JSON_values(
+ value, value switch
+ {
+ "00:00:00.0000000" => """{"Prop":"00:00:00"}""",
+ "23:59:59.9999999" => """{"Prop":"23:59:59.9999999"}""",
+ "11:05:12.3456789" => """{"Prop":"11:05:12.3456789"}""",
+ _ => throw new ArgumentOutOfRangeException(nameof(value), value, null)
+ });
+
+ public override Task Can_read_write_nullable_TimeOnly_JSON_values(string? value, string json)
+ => base.Can_read_write_nullable_TimeOnly_JSON_values(
+ value, value switch
+ {
+ "00:00:00.0000000" => """{"Prop":"00:00:00"}""",
+ "23:59:59.9999999" => """{"Prop":"23:59:59.9999999"}""",
+ "11:05:12.3456789" => """{"Prop":"11:05:12.3456789"}""",
+ null => """{"Prop":null}""",
+ _ => throw new ArgumentOutOfRangeException(nameof(value), value, null)
+ });
+
+ public override Task Can_read_write_collection_of_TimeOnly_JSON_values()
+ => Can_read_and_write_JSON_value>(
+ nameof(TimeOnlyCollectionType.TimeOnly),
+ [
+ TimeOnly.MinValue,
+ new TimeOnly(11, 5, 2, 3, 4),
+ TimeOnly.MaxValue
+ ],
+ """{"Prop":["00:00:00","11:05:02.0030040","23:59:59.9999999"]}""",
+ mappedCollection: true,
+ new List());
+
+ public override Task Can_read_write_collection_of_nullable_TimeOnly_JSON_values()
+ => Can_read_and_write_JSON_value>(
+ nameof(NullableTimeOnlyCollectionType.TimeOnly),
+ [
+ null,
+ TimeOnly.MinValue,
+ new TimeOnly(11, 5, 2, 3, 4),
+ TimeOnly.MaxValue
+ ],
+ """{"Prop":[null,"00:00:00","11:05:02.0030040","23:59:59.9999999"]}""",
+ mappedCollection: true);
+
public override Task Can_read_write_ulong_enum_JSON_values(EnumU64 value, string json)
=> Can_read_and_write_JSON_value(nameof(EnumU64Type.EnumU64), value, json);
diff --git a/test/EFCore.Sqlite.FunctionalTests/Scaffolding/Baselines/BigModel/ManyTypesEntityType.cs b/test/EFCore.Sqlite.FunctionalTests/Scaffolding/Baselines/BigModel/ManyTypesEntityType.cs
index 92d0ef51ea3..a954d48cebc 100644
--- a/test/EFCore.Sqlite.FunctionalTests/Scaffolding/Baselines/BigModel/ManyTypesEntityType.cs
+++ b/test/EFCore.Sqlite.FunctionalTests/Scaffolding/Baselines/BigModel/ManyTypesEntityType.cs
@@ -12219,9 +12219,9 @@ public static RuntimeEntityType Create(RuntimeModel model, RuntimeEntityType bas
int (string v) => ((object)v).GetHashCode(),
string (string v) => v),
converter: new CollectionToJsonStringConverter(new JsonCollectionOfNullableStructsReaderWriter(
- JsonTimeOnlyReaderWriter.Instance)),
+ SqliteJsonTimeOnlyReaderWriter.Instance)),
jsonValueReaderWriter: new JsonCollectionOfNullableStructsReaderWriter(
- JsonTimeOnlyReaderWriter.Instance),
+ SqliteJsonTimeOnlyReaderWriter.Instance),
elementMapping: SqliteTimeOnlyTypeMapping.Default);
var nullableTimeOnlyArrayElementType = nullableTimeOnlyArray.SetElementType(typeof(TimeOnly?),
nullable: true);
@@ -13956,7 +13956,7 @@ public static RuntimeEntityType Create(RuntimeModel model, RuntimeEntityType bas
TimeOnly (string v) => TimeOnly.Parse(v, CultureInfo.InvariantCulture, DateTimeStyles.None),
string (TimeOnly v) => (v.Ticks % 10000000L == 0L ? string.Format(CultureInfo.InvariantCulture, "{0:HH\\:mm\\:ss}", ((object)(v))) : v.ToString("o"))),
jsonValueReaderWriter: new JsonConvertedValueReaderWriter(
- JsonTimeOnlyReaderWriter.Instance,
+ SqliteJsonTimeOnlyReaderWriter.Instance,
new ValueConverter(
TimeOnly (string v) => TimeOnly.Parse(v, CultureInfo.InvariantCulture, DateTimeStyles.None),
string (TimeOnly v) => (v.Ticks % 10000000L == 0L ? string.Format(CultureInfo.InvariantCulture, "{0:HH\\:mm\\:ss}", ((object)(v))) : v.ToString("o")))));
@@ -14151,9 +14151,9 @@ public static RuntimeEntityType Create(RuntimeModel model, RuntimeEntityType bas
int (string v) => ((object)v).GetHashCode(),
string (string v) => v),
converter: new CollectionToJsonStringConverter(new JsonCollectionOfStructsReaderWriter(
- JsonTimeOnlyReaderWriter.Instance)),
+ SqliteJsonTimeOnlyReaderWriter.Instance)),
jsonValueReaderWriter: new JsonCollectionOfStructsReaderWriter(
- JsonTimeOnlyReaderWriter.Instance),
+ SqliteJsonTimeOnlyReaderWriter.Instance),
elementMapping: SqliteTimeOnlyTypeMapping.Default);
var timeOnlyArrayElementType = timeOnlyArray.SetElementType(typeof(TimeOnly));
timeOnlyArrayElementType.TypeMapping = timeOnlyArray.TypeMapping.ElementTypeMapping;
diff --git a/test/EFCore.Sqlite.FunctionalTests/Scaffolding/Baselines/BigModel_with_JSON_columns/ManyTypesEntityType.cs b/test/EFCore.Sqlite.FunctionalTests/Scaffolding/Baselines/BigModel_with_JSON_columns/ManyTypesEntityType.cs
index 92d0ef51ea3..a954d48cebc 100644
--- a/test/EFCore.Sqlite.FunctionalTests/Scaffolding/Baselines/BigModel_with_JSON_columns/ManyTypesEntityType.cs
+++ b/test/EFCore.Sqlite.FunctionalTests/Scaffolding/Baselines/BigModel_with_JSON_columns/ManyTypesEntityType.cs
@@ -12219,9 +12219,9 @@ public static RuntimeEntityType Create(RuntimeModel model, RuntimeEntityType bas
int (string v) => ((object)v).GetHashCode(),
string (string v) => v),
converter: new CollectionToJsonStringConverter(new JsonCollectionOfNullableStructsReaderWriter(
- JsonTimeOnlyReaderWriter.Instance)),
+ SqliteJsonTimeOnlyReaderWriter.Instance)),
jsonValueReaderWriter: new JsonCollectionOfNullableStructsReaderWriter(
- JsonTimeOnlyReaderWriter.Instance),
+ SqliteJsonTimeOnlyReaderWriter.Instance),
elementMapping: SqliteTimeOnlyTypeMapping.Default);
var nullableTimeOnlyArrayElementType = nullableTimeOnlyArray.SetElementType(typeof(TimeOnly?),
nullable: true);
@@ -13956,7 +13956,7 @@ public static RuntimeEntityType Create(RuntimeModel model, RuntimeEntityType bas
TimeOnly (string v) => TimeOnly.Parse(v, CultureInfo.InvariantCulture, DateTimeStyles.None),
string (TimeOnly v) => (v.Ticks % 10000000L == 0L ? string.Format(CultureInfo.InvariantCulture, "{0:HH\\:mm\\:ss}", ((object)(v))) : v.ToString("o"))),
jsonValueReaderWriter: new JsonConvertedValueReaderWriter(
- JsonTimeOnlyReaderWriter.Instance,
+ SqliteJsonTimeOnlyReaderWriter.Instance,
new ValueConverter(
TimeOnly (string v) => TimeOnly.Parse(v, CultureInfo.InvariantCulture, DateTimeStyles.None),
string (TimeOnly v) => (v.Ticks % 10000000L == 0L ? string.Format(CultureInfo.InvariantCulture, "{0:HH\\:mm\\:ss}", ((object)(v))) : v.ToString("o")))));
@@ -14151,9 +14151,9 @@ public static RuntimeEntityType Create(RuntimeModel model, RuntimeEntityType bas
int (string v) => ((object)v).GetHashCode(),
string (string v) => v),
converter: new CollectionToJsonStringConverter(new JsonCollectionOfStructsReaderWriter(
- JsonTimeOnlyReaderWriter.Instance)),
+ SqliteJsonTimeOnlyReaderWriter.Instance)),
jsonValueReaderWriter: new JsonCollectionOfStructsReaderWriter(
- JsonTimeOnlyReaderWriter.Instance),
+ SqliteJsonTimeOnlyReaderWriter.Instance),
elementMapping: SqliteTimeOnlyTypeMapping.Default);
var timeOnlyArrayElementType = timeOnlyArray.SetElementType(typeof(TimeOnly));
timeOnlyArrayElementType.TypeMapping = timeOnlyArray.TypeMapping.ElementTypeMapping;
diff --git a/test/EFCore.Sqlite.FunctionalTests/Types/SqliteMiscellaneousTypeTest.cs b/test/EFCore.Sqlite.FunctionalTests/Types/SqliteMiscellaneousTypeTest.cs
index 442772613a1..30282e9a745 100644
--- a/test/EFCore.Sqlite.FunctionalTests/Types/SqliteMiscellaneousTypeTest.cs
+++ b/test/EFCore.Sqlite.FunctionalTests/Types/SqliteMiscellaneousTypeTest.cs
@@ -43,9 +43,8 @@ public class GuidTypeFixture : SqliteTypeFixture
public class SqliteByteArrayTypeTest(SqliteByteArrayTypeTest.ByteArrayTypeFixture fixture, ITestOutputHelper testOutputHelper)
: RelationalTypeTestBase(fixture, testOutputHelper)
{
- // TODO: string representation discrepancy between our JSON and M.D.SQLite's string representation, see #36749.
- public override Task Query_property_within_json()
- => Assert.ThrowsAsync(() => base.Query_property_within_json());
+
+ public override Task Query_property_within_json() => base.Query_property_within_json();
public override async Task ExecuteUpdate_within_json_to_nonjson_column()
{
diff --git a/test/EFCore.Sqlite.FunctionalTests/Types/SqliteTemporalTypeTest.cs b/test/EFCore.Sqlite.FunctionalTests/Types/SqliteTemporalTypeTest.cs
index d3655b6a938..a600f064897 100644
--- a/test/EFCore.Sqlite.FunctionalTests/Types/SqliteTemporalTypeTest.cs
+++ b/test/EFCore.Sqlite.FunctionalTests/Types/SqliteTemporalTypeTest.cs
@@ -57,9 +57,9 @@ public class DateTypeFixture : SqliteTypeFixture
public class SqliteTimeOnlyTypeTest(SqliteTimeOnlyTypeTest.TimeTypeFixture fixture, ITestOutputHelper testOutputHelper)
: RelationalTypeTestBase(fixture, testOutputHelper)
{
- // TODO: string representation discrepancy between our JSON and M.D.SQLite's string representation, see #36749.
+
public override Task Query_property_within_json()
- => Assert.ThrowsAsync(() => base.Query_property_within_json());
+ => base.Query_property_within_json();
public override async Task ExecuteUpdate_within_json_to_nonjson_column()
{
diff --git a/test/EFCore.Sqlite.FunctionalTests/Update/JsonUpdateSqliteTest.cs b/test/EFCore.Sqlite.FunctionalTests/Update/JsonUpdateSqliteTest.cs
index b1905c54a5e..57537571af5 100644
--- a/test/EFCore.Sqlite.FunctionalTests/Update/JsonUpdateSqliteTest.cs
+++ b/test/EFCore.Sqlite.FunctionalTests/Update/JsonUpdateSqliteTest.cs
@@ -1146,8 +1146,8 @@ public override async Task Edit_two_properties_on_same_entity_updates_the_entire
AssertSql(
"""
-@p0='{"TestBoolean":false,"TestBooleanCollection":[true,false],"TestByte":25,"TestByteArray":"","TestByteCollection":null,"TestCharacter":"h","TestCharacterCollection":["A","B","\u0022"],"TestDateOnly":"2323-04-03","TestDateOnlyCollection":["3234-01-23","4331-01-21"],"TestDateTime":"2100-11-11 12:34:56","TestDateTimeCollection":["2000-01-01 12:34:56","3000-01-01 12:34:56"],"TestDateTimeOffset":"2200-11-11 12:34:56-05:00","TestDateTimeOffsetCollection":["2000-01-01 12:34:56-08:00"],"TestDecimal":"-123450.01","TestDecimalCollection":["-1234567890.01"],"TestDefaultString":"MyDefaultStringInCollection1","TestDefaultStringCollection":["S1","\u0022S2\u0022","S3"],"TestDouble":-1.2345,"TestDoubleCollection":[-1.23456789,1.23456789,0],"TestEnum":-1,"TestEnumCollection":[-1,-3,-7],"TestEnumWithIntConverter":2,"TestEnumWithIntConverterCollection":[-1,-3,-7],"TestGuid":"00000000-0000-0000-0000-000000000000","TestGuidCollection":["12345678-1234-4321-7777-987654321000"],"TestInt16":-12,"TestInt16Collection":[-32768,0,32767],"TestInt32":32,"TestInt32Collection":[-2147483648,0,2147483647],"TestInt64":64,"TestInt64Collection":[-9223372036854775808,0,9223372036854775807],"TestMaxLengthString":"Baz","TestMaxLengthStringCollection":["S1","S2","S3"],"TestNullableEnum":-1,"TestNullableEnumCollection":[-1,null,-3,-7],"TestNullableEnumWithConverterThatHandlesNulls":"Two","TestNullableEnumWithConverterThatHandlesNullsCollection":[-1,null,-7],"TestNullableEnumWithIntConverter":-3,"TestNullableEnumWithIntConverterCollection":[-1,null,-3,-7],"TestNullableInt32":90,"TestNullableInt32Collection":[null,-2147483648,0,null,2147483647,null],"TestSignedByte":-18,"TestSignedByteCollection":[-128,0,127],"TestSingle":-1.4,"TestSingleCollection":[-1.234,0,-1.234],"TestTimeOnly":"05:07:08.0000000","TestTimeOnlyCollection":["13:42:23.0000000","07:17:25.0000000"],"TestTimeSpan":"6:05:04.003","TestTimeSpanCollection":["10:09:08.007","-9:50:51.993"],"TestUnsignedInt16":12,"TestUnsignedInt16Collection":[0,0,65535],"TestUnsignedInt32":12345,"TestUnsignedInt32Collection":[0,0,4294967295],"TestUnsignedInt64":1234567867,"TestUnsignedInt64Collection":[0,0,9223372036854775807]}' (Nullable = false) (Size = 2161)
-@p1='{"TestBoolean":true,"TestBooleanCollection":[true,false],"TestByte":255,"TestByteArray":"010203","TestByteCollection":null,"TestCharacter":"a","TestCharacterCollection":["A","B","\u0022"],"TestDateOnly":"2023-10-10","TestDateOnlyCollection":["1234-01-23","4321-01-21"],"TestDateTime":"2000-01-01 12:34:56","TestDateTimeCollection":["2000-01-01 12:34:56","3000-01-01 12:34:56"],"TestDateTimeOffset":"2000-01-01 12:34:56-08:00","TestDateTimeOffsetCollection":["2000-01-01 12:34:56-08:00"],"TestDecimal":"-1234567890.01","TestDecimalCollection":["-1234567890.01"],"TestDefaultString":"MyDefaultStringInReference1","TestDefaultStringCollection":["S1","\u0022S2\u0022","S3"],"TestDouble":-1.23456789,"TestDoubleCollection":[-1.23456789,1.23456789,0],"TestEnum":-1,"TestEnumCollection":[-1,-3,-7],"TestEnumWithIntConverter":2,"TestEnumWithIntConverterCollection":[-1,-3,-7],"TestGuid":"12345678-1234-4321-7777-987654321000","TestGuidCollection":["12345678-1234-4321-7777-987654321000"],"TestInt16":-1234,"TestInt16Collection":[-32768,0,32767],"TestInt32":32,"TestInt32Collection":[-2147483648,0,2147483647],"TestInt64":64,"TestInt64Collection":[-9223372036854775808,0,9223372036854775807],"TestMaxLengthString":"Foo","TestMaxLengthStringCollection":["S1","S2","S3"],"TestNullableEnum":-1,"TestNullableEnumCollection":[-1,null,-3,-7],"TestNullableEnumWithConverterThatHandlesNulls":"Three","TestNullableEnumWithConverterThatHandlesNullsCollection":[-1,null,-7],"TestNullableEnumWithIntConverter":2,"TestNullableEnumWithIntConverterCollection":[-1,null,-3,-7],"TestNullableInt32":78,"TestNullableInt32Collection":[null,-2147483648,0,null,2147483647,null],"TestSignedByte":-128,"TestSignedByteCollection":[-128,0,127],"TestSingle":-1.234,"TestSingleCollection":[-1.234,0,-1.234],"TestTimeOnly":"11:12:13.0000000","TestTimeOnlyCollection":["11:42:23.0000000","07:17:27.0000000"],"TestTimeSpan":"10:09:08.007","TestTimeSpanCollection":["10:09:08.007","-9:50:51.993"],"TestUnsignedInt16":1234,"TestUnsignedInt16Collection":[0,0,65535],"TestUnsignedInt32":1234565789,"TestUnsignedInt32Collection":[0,0,4294967295],"TestUnsignedInt64":1234567890123456789,"TestUnsignedInt64Collection":[0,0,9223372036854775807]}' (Nullable = false) (Size = 2197)
+@p0='{"TestBoolean":false,"TestBooleanCollection":[true,false],"TestByte":25,"TestByteArray":"","TestByteCollection":null,"TestCharacter":"h","TestCharacterCollection":["A","B","\u0022"],"TestDateOnly":"2323-04-03","TestDateOnlyCollection":["3234-01-23","4331-01-21"],"TestDateTime":"2100-11-11 12:34:56","TestDateTimeCollection":["2000-01-01 12:34:56","3000-01-01 12:34:56"],"TestDateTimeOffset":"2200-11-11 12:34:56-05:00","TestDateTimeOffsetCollection":["2000-01-01 12:34:56-08:00"],"TestDecimal":"-123450.01","TestDecimalCollection":["-1234567890.01"],"TestDefaultString":"MyDefaultStringInCollection1","TestDefaultStringCollection":["S1","\u0022S2\u0022","S3"],"TestDouble":-1.2345,"TestDoubleCollection":[-1.23456789,1.23456789,0],"TestEnum":-1,"TestEnumCollection":[-1,-3,-7],"TestEnumWithIntConverter":2,"TestEnumWithIntConverterCollection":[-1,-3,-7],"TestGuid":"00000000-0000-0000-0000-000000000000","TestGuidCollection":["12345678-1234-4321-7777-987654321000"],"TestInt16":-12,"TestInt16Collection":[-32768,0,32767],"TestInt32":32,"TestInt32Collection":[-2147483648,0,2147483647],"TestInt64":64,"TestInt64Collection":[-9223372036854775808,0,9223372036854775807],"TestMaxLengthString":"Baz","TestMaxLengthStringCollection":["S1","S2","S3"],"TestNullableEnum":-1,"TestNullableEnumCollection":[-1,null,-3,-7],"TestNullableEnumWithConverterThatHandlesNulls":"Two","TestNullableEnumWithConverterThatHandlesNullsCollection":[-1,null,-7],"TestNullableEnumWithIntConverter":-3,"TestNullableEnumWithIntConverterCollection":[-1,null,-3,-7],"TestNullableInt32":90,"TestNullableInt32Collection":[null,-2147483648,0,null,2147483647,null],"TestSignedByte":-18,"TestSignedByteCollection":[-128,0,127],"TestSingle":-1.4,"TestSingleCollection":[-1.234,0,-1.234],"TestTimeOnly":"05:07:08","TestTimeOnlyCollection":["13:42:23","07:17:25"],"TestTimeSpan":"6:05:04.003","TestTimeSpanCollection":["10:09:08.007","-9:50:51.993"],"TestUnsignedInt16":12,"TestUnsignedInt16Collection":[0,0,65535],"TestUnsignedInt32":12345,"TestUnsignedInt32Collection":[0,0,4294967295],"TestUnsignedInt64":1234567867,"TestUnsignedInt64Collection":[0,0,9223372036854775807]}' (Nullable = false) (Size = 2137)
+@p1='{"TestBoolean":true,"TestBooleanCollection":[true,false],"TestByte":255,"TestByteArray":"010203","TestByteCollection":null,"TestCharacter":"a","TestCharacterCollection":["A","B","\u0022"],"TestDateOnly":"2023-10-10","TestDateOnlyCollection":["1234-01-23","4321-01-21"],"TestDateTime":"2000-01-01 12:34:56","TestDateTimeCollection":["2000-01-01 12:34:56","3000-01-01 12:34:56"],"TestDateTimeOffset":"2000-01-01 12:34:56-08:00","TestDateTimeOffsetCollection":["2000-01-01 12:34:56-08:00"],"TestDecimal":"-1234567890.01","TestDecimalCollection":["-1234567890.01"],"TestDefaultString":"MyDefaultStringInReference1","TestDefaultStringCollection":["S1","\u0022S2\u0022","S3"],"TestDouble":-1.23456789,"TestDoubleCollection":[-1.23456789,1.23456789,0],"TestEnum":-1,"TestEnumCollection":[-1,-3,-7],"TestEnumWithIntConverter":2,"TestEnumWithIntConverterCollection":[-1,-3,-7],"TestGuid":"12345678-1234-4321-7777-987654321000","TestGuidCollection":["12345678-1234-4321-7777-987654321000"],"TestInt16":-1234,"TestInt16Collection":[-32768,0,32767],"TestInt32":32,"TestInt32Collection":[-2147483648,0,2147483647],"TestInt64":64,"TestInt64Collection":[-9223372036854775808,0,9223372036854775807],"TestMaxLengthString":"Foo","TestMaxLengthStringCollection":["S1","S2","S3"],"TestNullableEnum":-1,"TestNullableEnumCollection":[-1,null,-3,-7],"TestNullableEnumWithConverterThatHandlesNulls":"Three","TestNullableEnumWithConverterThatHandlesNullsCollection":[-1,null,-7],"TestNullableEnumWithIntConverter":2,"TestNullableEnumWithIntConverterCollection":[-1,null,-3,-7],"TestNullableInt32":78,"TestNullableInt32Collection":[null,-2147483648,0,null,2147483647,null],"TestSignedByte":-128,"TestSignedByteCollection":[-128,0,127],"TestSingle":-1.234,"TestSingleCollection":[-1.234,0,-1.234],"TestTimeOnly":"11:12:13","TestTimeOnlyCollection":["11:42:23","07:17:27"],"TestTimeSpan":"10:09:08.007","TestTimeSpanCollection":["10:09:08.007","-9:50:51.993"],"TestUnsignedInt16":1234,"TestUnsignedInt16Collection":[0,0,65535],"TestUnsignedInt32":1234565789,"TestUnsignedInt32Collection":[0,0,4294967295],"TestUnsignedInt64":1234567890123456789,"TestUnsignedInt64Collection":[0,0,9223372036854775807]}' (Nullable = false) (Size = 2173)
@p2='1'
UPDATE "JsonEntitiesAllTypes" SET "Collection" = json_set("Collection", '$[0]', json(@p0)), "Reference" = @p1
@@ -1726,8 +1726,8 @@ public override async Task Edit_single_property_collection_of_timeonly()
AssertSql(
"""
-@p0='["13:42:23.0000000","01:01:07.0000000"]' (Nullable = false) (Size = 39)
-@p1='["01:01:07.0000000","07:17:27.0000000"]' (Nullable = false) (Size = 39)
+@p0='["13:42:23","01:01:07"]' (Nullable = false) (Size = 23)
+@p1='["01:01:07","07:17:27"]' (Nullable = false) (Size = 23)
@p2='1'
UPDATE "JsonEntitiesAllTypes" SET "Collection" = json_set("Collection", '$[0].TestTimeOnlyCollection', json(@p0)), "Reference" = json_set("Reference", '$.TestTimeOnlyCollection', json(@p1))
@@ -2295,9 +2295,9 @@ public override async Task Add_and_update_nested_optional_primitive_collection(b
var parameterSize = value switch
{
- true => "1562",
- false => "1559",
- _ => "1561"
+ true => "1554",
+ false => "1551",
+ _ => "1553"
};
var updateParameter = value switch
@@ -2310,7 +2310,7 @@ public override async Task Add_and_update_nested_optional_primitive_collection(b
AssertSql(
@"@p0='[{""TestBoolean"":false,""TestBooleanCollection"":[],""TestByte"":0,""TestByteArray"":null,""TestByteCollection"":null,""TestCharacter"":""\u0000"",""TestCharacterCollection"":"
+ characterCollection
- + @",""TestDateOnly"":""0001-01-01"",""TestDateOnlyCollection"":[],""TestDateTime"":""0001-01-01 00:00:00"",""TestDateTimeCollection"":[],""TestDateTimeOffset"":""0001-01-01 00:00:00+00:00"",""TestDateTimeOffsetCollection"":[],""TestDecimal"":""0.0"",""TestDecimalCollection"":[],""TestDefaultString"":null,""TestDefaultStringCollection"":[],""TestDouble"":0,""TestDoubleCollection"":[],""TestEnum"":0,""TestEnumCollection"":[],""TestEnumWithIntConverter"":0,""TestEnumWithIntConverterCollection"":[],""TestGuid"":""00000000-0000-0000-0000-000000000000"",""TestGuidCollection"":[],""TestInt16"":0,""TestInt16Collection"":[],""TestInt32"":0,""TestInt32Collection"":[],""TestInt64"":0,""TestInt64Collection"":[],""TestMaxLengthString"":null,""TestMaxLengthStringCollection"":[],""TestNullableEnum"":null,""TestNullableEnumCollection"":[],""TestNullableEnumWithConverterThatHandlesNulls"":null,""TestNullableEnumWithConverterThatHandlesNullsCollection"":[],""TestNullableEnumWithIntConverter"":null,""TestNullableEnumWithIntConverterCollection"":[],""TestNullableInt32"":null,""TestNullableInt32Collection"":[],""TestSignedByte"":0,""TestSignedByteCollection"":[],""TestSingle"":0,""TestSingleCollection"":[],""TestTimeOnly"":""00:00:00.0000000"",""TestTimeOnlyCollection"":[],""TestTimeSpan"":""0:00:00"",""TestTimeSpanCollection"":[],""TestUnsignedInt16"":0,""TestUnsignedInt16Collection"":[],""TestUnsignedInt32"":0,""TestUnsignedInt32Collection"":[],""TestUnsignedInt64"":0,""TestUnsignedInt64Collection"":[]}]' (Nullable = false) (Size = "
+ + @",""TestDateOnly"":""0001-01-01"",""TestDateOnlyCollection"":[],""TestDateTime"":""0001-01-01 00:00:00"",""TestDateTimeCollection"":[],""TestDateTimeOffset"":""0001-01-01 00:00:00+00:00"",""TestDateTimeOffsetCollection"":[],""TestDecimal"":""0.0"",""TestDecimalCollection"":[],""TestDefaultString"":null,""TestDefaultStringCollection"":[],""TestDouble"":0,""TestDoubleCollection"":[],""TestEnum"":0,""TestEnumCollection"":[],""TestEnumWithIntConverter"":0,""TestEnumWithIntConverterCollection"":[],""TestGuid"":""00000000-0000-0000-0000-000000000000"",""TestGuidCollection"":[],""TestInt16"":0,""TestInt16Collection"":[],""TestInt32"":0,""TestInt32Collection"":[],""TestInt64"":0,""TestInt64Collection"":[],""TestMaxLengthString"":null,""TestMaxLengthStringCollection"":[],""TestNullableEnum"":null,""TestNullableEnumCollection"":[],""TestNullableEnumWithConverterThatHandlesNulls"":null,""TestNullableEnumWithConverterThatHandlesNullsCollection"":[],""TestNullableEnumWithIntConverter"":null,""TestNullableEnumWithIntConverterCollection"":[],""TestNullableInt32"":null,""TestNullableInt32Collection"":[],""TestSignedByte"":0,""TestSignedByteCollection"":[],""TestSingle"":0,""TestSingleCollection"":[],""TestTimeOnly"":""00:00:00"",""TestTimeOnlyCollection"":[],""TestTimeSpan"":""0:00:00"",""TestTimeSpanCollection"":[],""TestUnsignedInt16"":0,""TestUnsignedInt16Collection"":[],""TestUnsignedInt32"":0,""TestUnsignedInt32Collection"":[],""TestUnsignedInt64"":0,""TestUnsignedInt64Collection"":[]}]' (Nullable = false) (Size = "
+ parameterSize
+ @")
@p1='7624'