EF Core 7.0 – JSON Column

Posted dotNET跨平台

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了EF Core 7.0 – JSON Column相关的知识,希望对你有一定的参考价值。

前言

SQL Server 支持 JSON, 以前写过一篇介绍 SQL Server – Work with JSON.  但 EF Core 一直没有支持。直到 EF Core 7.0 才支持。

EF Core 7 包含对 JSON 列的提供程序无关的支持,以及 SQL Server 的实现。此支持允许将从 .NET 类型生成的聚合映射到 JSON 文档。可以在聚合上使用普通的 LINQ 查询,这些查询将转换为钻取到 JSON 所需的相应查询构造。EF7 还支持更新和保存对 JSON 文档所做的更改。具体参考 https://learn.microsoft.com/zh-cn/ef/core/what-is-new/ef-core-7.0/whatsnew#json-columns

配置

public class Customer

    public int Id  get; set; 
    public string Name  get; set;  = "";
    public Address Address  get; set;  = null!;


public class Address

    public string Line1  get; set;  = "";
    public string Line2  get; set;  = "";

Address 是一个对象. 过往我们会把它配置成 Owned Entity, 属性 Line1, Line2 分别占据数据库 2 个 column. column name 是 Address_Line1, Address_Line2

这样是 ok 的, 但有时候我们希望它在数据库就一个 column, 然后用 JSON 格式保存资料. 反正数据库也支持 JSON 查询 (只是性能不容易优化), 一堆 column 毕竟很乱.

声明使用 JSON Column

它算是 Owned Entity 的扩展, 表面上依然是 Owned Entity, 但多了一个 ToJson() 声明

modelBuilder.Entity<Customer>().ToTable("Customer");
modelBuilder.Entity<Customer>().Property(e => e.Name).HasMaxLength(256);
modelBuilder.Entity<Customer>().OwnsOne(e => e.Address, addressBuilder =>

    addressBuilder.ToJson();
    addressBuilder.Property(e => e.Line1).HasMaxLength(256);
    addressBuilder.Property(e => e.Line2).HasMaxLength(256);
);

数据库长相

生成出来的数据长这样. Address 值就是 JSON 格式

查询的 LINQ 是完全一样的, EF Core 在背地里会转换成对应的 JSON Query

var c
ustomers = await db.Customers.Where(e => e.Address.Line1 == "lorem 1").ToListAsync();

Query

嵌套

如果有多层, 只需要在最上层设置 ToJson() 就可以了.

Update Value

像平常一样直接 update Entity 就可以了. EF Core 会转换成 JSON_MODIFY 语句去更新

Array OwnsMany

除了对象, Array 也是可以的. 使用 OwnsMany. 操作和 OwnsOne 一摸一样.

但是 List<string> 就没有办法哦. 而且 Array 是不支持过滤的.

modelBuilder.Entity<Customer>().OwnsMany(e => e.Addresses, addressesBuilder =>

    addressesBuilder.ToJson();
    addressesBuilder.Property(e => e.Line1).HasMaxLength(256);
    addressesBuilder.Property(e => e.Line2).HasMaxLength(256);
);

query

var customer = await db.Customers.Where(e => e.Addresses.Count() > 3).ToListAsync();

上面这句会直接报错...目前还不支持 

Limitation

Github – Support spatial types in JSON columns :https://github.com/dotnet/efcore/issues/28811

Github – Json: add support for collection of primitive types:https://github.com/dotnet/efcore/issues/28688

Github – Support LINQ to JSONPATH querying:https://github.com/dotnet/efcore/issues/28616

以上是关于EF Core 7.0 – JSON Column的主要内容,如果未能解决你的问题,请参考以下文章

EF Core查询jsonb

EF Core 3.1 无法查询 Json 序列化对象

关于ef core 将实体类生成到类库 , 将appsettings.json生成到debug目录下

EF Core 复杂的 where 子句

EF Core 5 - 如何将 EF.Functions.Like 与映射到 JSON 字符串的自定义属性一起使用?

EF Core:实体类型“用户”需要定义主键