使用 EF 核心更新 JSON 属性的最佳方法

Sta*_*lav 4 .net sql-server entity-framework entity-framework-core .net-core

我考虑将一些信息作为 JSON 对象存储在 SQL Server 数据库中,但我不清楚我应该如何更新 JSON 列中该对象的单个属性而不是整个对象。

它是一个asp.net 核心应用程序。作为 ORM,我使用实体框架核心。我想创建一个看起来像这个例子的类:

public class Person{
  public int Id {get;set;}
  public string FirstName {get;set;}
  public string  LastName {get;set;}  
  public string AdditionData {get;set;} //json object
}
Run Code Online (Sandbox Code Playgroud)

“AdditionData”列中的 JSON 对象将具有以下格式:

{
  phoneNumbers:["123456789","789456123"],
  groups:[{name:"g1", description:"blah"}, {name:"g2", description:"blah2"}]
}
Run Code Online (Sandbox Code Playgroud)

所以现在我想向某人添加新的 PhoneNumber 并且方法签名可能如下所示:

void AddPhoneNumber(int personId, string phoneNumber);
Run Code Online (Sandbox Code Playgroud)

我发现只有两个选项如何将新的 phoneNumber 添加到描述的对象。

第一个:1) 使用 EF 通过 id 查找人员 2) 从字符串中反序列化整个 AdditionData 对象 3) 将新的 phoneNumber 添加到 additionalData.PhoneNumbers 列表 4) 将 AdditionData 对象序列化回字符串 5) 使用此字符串更新 person.AdditionData 属性 6) 执行“保存更改”

第二个:使用 JSON_MODIFY sql 函数并使用如下参数执行原始 sql:

context.Database.ExecuteSqlCommand("UPDATE Person
SET additionalData = JSON_MODIFY(additionalData,"append  $.phoneNumbers", @phoneNumber)
WHERE Id= @personId", personIdParam,phoneNumberParam);
Run Code Online (Sandbox Code Playgroud)

问题:是否存在另一种方法来做到这一点?因为我描述的这两种方式看起来不太优雅(尤其是第一种)。

Ang*_*nov 5

从 EF Core 2.2 开始,这是不可能的。有这样一个功能的提议,但我不会屏住呼吸。

如果您存储的 JSON 很小和/或更新很少,我会采用第一种方法,因为更改存储在上下文中并且您不需要事务并且更好地与 EF 的整体设计保持一致。此外,它还为您提供了编译时安全性,并且更容易重构/更改。查看此线程 -如何使用 EF Core 在实体字段中存储 JSON?

如果您需要性能,那么绝对是 JSON_MODIFY sql 命令。