Skip to content

[Bug]: TimeSpan parsing bug in Jsonb #2774

@dashiell-zhang

Description

@dashiell-zhang
public class TTest 
    {
        public long Id { get; set; }

        public string Name { get; set; }

        [Column(TypeName = "jsonb")]
        public AddressDetail Address { get; set; }

        public class AddressDetail
        {
            public TimeSpan A33 { get; set; }
        }
    }
            TimeSpan sdt = TimeSpan.FromSeconds(123);

            var info = db.TTest.Where(t => t.Address.A33 == sdt).FirstOrDefault();

. NET 7, when querying the TimeSpan type data in jsonb, I get an error Can't write CLR type System.

A direct comparison of a TimeSpan field will result in the above error,However, if you compare a specific property of TimeSpan, the above error does not occur, but although no error is reported, there is no result of the query

TimeSpan sdt = TimeSpan.FromSeconds(123);

            TTest test = new();
            test.Id = idHelper.GetId();
            test.CreateTime = DateTime.UtcNow;
            test.Name = "";
            test.Address = new()
            {
                A33 = sdt
            };

            db.TTest.Add(test);

            db.SaveChanges();

            var info = db.TTest.Where(t => t.Address.A33.Seconds == sdt.Seconds).FirstOrDefault();
info: Microsoft.EntityFrameworkCore.Database.Command[20101]
      Executed DbCommand (10ms) [Parameters=[@__sdt_Seconds_0='?' (DbType = Int32)], CommandType='Text', CommandTimeout='30']
      SELECT t."Id", t."Address", t."CreateTime", t."DeleteTime", t."IsDelete", t."Name", t.xmin
      FROM "Test" AS t
      WHERE NOT (t."IsDelete") AND CAST(t."Address"#>>'{A33,Seconds}' AS integer) = @__sdt_Seconds_0
      LIMIT 1

image
There are actually records in the database that match the query criteria but they are not queried

The problem seems to be the resolution of the TimeSpan https://learn.microsoft.com/en-us/dotnet/core/compatibility/serialization/6.0/timespan-serialization-format

Previous behavior
In .NET 6 GA, source generators serialize TimeSpan values by outputting all public properties of the type, which is the default serialization behavior for objects:

{"days":0,"hours":0,"milliseconds":0,"minutes":0,"seconds":1,"ticks":10000000,"totalDays":1.1574074074074073E-05,"totalHours":0.0002777777777777778,"totalMilliseconds":1000,"totalMinutes":0.016666666666666666,"totalSeconds":1}

New behavior
In servicing release .NET 6.0.2, source generators serialize TimeSpan values in the following format, which is consistent with the reflection-based serializer format:

"00:00:01"

It seems that the old parsed lines are used when querying a property of TimeSpan, such as the value of seconds, for comparison

Metadata

Metadata

Assignees

Labels

No labels
No labels

Type

Projects

No projects

Milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions