我正在使用 EF Core 8 和 Postgres 适配器。
我需要这个实体属性作为 JSON:
public ICollection<string> Messages { get; } = [];
我尝试过这个配置:
builder.OwnsOne(x => x.Messages, x => x.ToJson());
这不起作用,因为它已将
"{ Capacity: 4 }"
保存在数据库中。
我尝试过这个配置:
builder.Property(x => x.Messages).HasColumnType("jsonb");
这会引发
NotSupportedException
。
我尝试了各种其他组合和解决方法。
多年来,尽管 JSON 映射已得到改进,但始终存在错误或缺点。
我知道 .NET 9 昨天发布了,可能对基元和字符串集合进行了一些改进,但我们现在无法升级。
.NET 8 中有哪些功能?
我在值转换器的文档中找到了答案。尽管没有使用
HasColumnType("jsonb")
或 ToJson()
,它还是序列化为 json。
modelBuilder
.Entity<Customer>()
.Property(x => x.Messages)
//.HasColumnType("jsonb") // unnecessary
.HasConversion(
c => JsonSerializer.Serialize(c, JsonSerializerOptions.Default),
s => JsonSerializer.Deserialize<ICollection<string>>(s, JsonSerializerOptions.Default)!,
new ValueComparer<ICollection<string>>(
(c1, c2) => c1!.SequenceEqual(c2!),
c => c.Aggregate(0, (acc, val) => HashCode.Combine(acc, val.GetHashCode(StringComparison.Ordinal))),
c => new Collection<string>(c.ToList()))
);
示例:
customer.Messages.Add("foo");
customer.Messages.Add("bar");
customer.Messages.Add("baz");
数据库记录将有:
["foo","bar","baz"]