EF Core 7 SQL Server JsonColumn可空布尔值存为字符串致反序列化失败
问题:EF Core 7中JSON列可空布尔值序列化/反序列化异常
环境信息
已安装的NuGet包:
<PackageReference Include="Microsoft.EntityFrameworkCore" Version="7.0.8" /> <PackageReference Include="Microsoft.EntityFrameworkCore.Design" Version="7.0.8" /> <PackageReference Include="Microsoft.EntityFrameworkCore.Relational" Version="7.0.8"/> <PackageReference Include="Microsoft.EntityFrameworkCore.SqlServer" Version="7.0.8" />
实体与上下文配置
实体类定义
class B { public bool? B1 { get; set; } = false; public bool? B2 { get; set; } = false; public E1? SomeEnum { get; set; } = SomeEnum.SomeValue; }
DbContext配置
builder.Entity<A>(a => { a.OwnsOne(a => a.B, ownedNavigationBuilder => { ownedNavigationBuilder.ToJson(); ownedNavigationBuilder .Property(x => x.Y) .HasConversion(new EnumToNumberConverter<SomeEnum, int>()); }); });
问题详情
已通过EnumToNumberConverter将枚举转换为整数存储,这部分功能正常。但现在遇到新问题:保存包含B类型字段的实体A时,布尔值会被存储为字符串形式(如"true"、"false"),后续读取时抛出反序列化异常:
The JSON value could not be converted to System.Nullable`1[System.Boolean]. Path: $ | LineNumber: 0 | BytePositionInLine: 7.
查看数据库中存储为nvarchar的B列内容,发现布尔值存在两种格式:
{ B1: true, B2: "true" }
手动将"true"替换为true后,读取操作恢复正常。
完整调用堆栈如下:
An exception occurred while iterating over the results of a query for context type 'Management.Infra.ManagementContext'. System.Text.Json.JsonException: The JSON value could not be converted to System.Nullable`1[System.Boolean]. Path: $ | LineNumber: 0 | BytePositionInLine: 7. ---> System.InvalidOperationException: Cannot get the value of a token type 'String' as a boolean. at System.Text.Json.ThrowHelper.ThrowInvalidOperationException_ExpectedBoolean(JsonTokenType tokenType) at System.Text.Json.Serialization.Converters.BooleanConverter.Read(Utf8JsonReader& reader, Type typeToConvert, JsonSerializerOptions options) at System.Text.Json.Serialization.Converters.NullableConverter`1.Read(Utf8JsonReader& reader, Type typeToConvert, JsonSerializerOptions options) at System.Text.Json.Serialization.JsonConverter`1.TryRead(Utf8JsonReader& reader, Type typeToConvert, JsonSerializerOptions options, ReadStack& state, T& value) at System.Text.Json.Serialization.JsonConverter`1.ReadCore(Utf8JsonReader& reader, JsonSerializerOptions options, ReadStack& state) --- End of inner exception stack trace --- at System.Text.Json.ThrowHelper.ReThrowWithPath(ReadStack& state, Utf8JsonReader& reader, Exception ex) at System.Text.Json.Serialization.JsonConverter`1.ReadCore(Utf8JsonReader& reader, JsonSerializerOptions options, ReadStack& state) at System.Text.Json.JsonSerializer.ReadFromSpan[TValue](ReadOnlySpan`1 utf8Json, JsonTypeInfo jsonTypeInfo, Nullable`1 actualByteCount) at System.Text.Json.JsonSerializer.ReadUsingMetadata[TValue](JsonElement element, JsonTypeInfo jsonTypeInfo) at lambda_method514(Closure , QueryContext , Object[] , JsonElement ) at lambda_method513(Closure , QueryContext , DbDataReader , ResultContext , SplitQueryResultCoordinator ) at Microsoft.EntityFrameworkCore.Query.Internal.SplitQueryingEnumerable`1.AsyncEnumerator.MoveNextAsync()
临时处理方案(更新)
将B类中的可空布尔属性移除?改为非可空类型后,由于部分已存储的JSON缺少对应字段,读取时仍报错。运行迁移脚本补全所有JSON字段后,读写操作恢复正常。
推测这是EF Core 7中JSON列处理可空布尔值时的序列化/反序列化Bug。但该方案存在局限性:后续向B类添加新字段时,都需要编写JSON_MODIFY的SQL迁移脚本。目前正在尝试复现问题,计划复现后向GitHub提交Issue。
内容的提问来源于stack exchange,提问作者Juan Carlos
相关产品推荐
相关产品推荐

