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

zbdgwd5y  于 2023-01-03  发布在  .NET
关注(0)|答案(2)|浏览(288)

我考虑将一些信息作为JSON对象存储在SQL Server数据库中,但我不清楚应该如何更新JSON列中该对象的单个属性,而不是整个对象。
It is an asp.net core application. As ORM I use Entity Framework core. I want to create a class which will look like this example:

  1. public class Person{
  2. public int Id {get;set;}
  3. public string FirstName {get;set;}
  4. public string LastName {get;set;}
  5. public string AdditionData {get;set;} //json object
  6. }

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

  1. {
  2. phoneNumbers:["123456789","789456123"],
  3. groups:[{name:"g1", description:"blah"}, {name:"g2", description:"blah2"}]
  4. }

现在我想给某个人添加新的PhoneNumber,方法签名可能如下所示:

  1. void AddPhoneNumber(int personId, string phoneNumber);

我发现只有两个选项,我可以添加新的电话号码描述的对象。
第一种选择:
1.使用EF按ID查找人员
1.从字符串反序列化整个AdditionData对象
1.将新电话号码添加到添加数据.电话号码列表
1.将AdditionData对象序列化回字符串
1.使用此字符串更新person.AdditionData属性
1.执行"保存更改"
第二种选择:
使用JSON_MODIFY SQL函数并执行带参数的原始SQL,如下所示:

  1. context.Database.ExecuteSqlCommand("UPDATE Person
  2. SET additionalData = JSON_MODIFY(additionalData,"append $.phoneNumbers", @phoneNumber)
  3. WHERE Id= @personId", personIdParam,phoneNumberParam);

问题:有没有其他的方法可以做到这一点?因为我所描述的这两种方法在我看来并不优雅(尤其是第一种)。

pjngdqdw

pjngdqdw1#

这是不可能的,因为EF核心2. 2。有一个proposal为这样的功能,但我不会屏住呼吸。
如果你存储的JSON很小,而且更新很少,我会选择第一种方法,因为修改存储在上下文中,你不需要事务,而且更符合EF的整体设计。另外,它给你提供了编译时的安全性,更容易重构/修改。
如果你需要性能比肯定JSON_MODIFY sql命令。

7uzetpgm

7uzetpgm2#

EF 7.0升级版

现在您可以使用EF 7为SQL Server创建Json列,还可以更新Json属性:

  1. public class Person
  2. {
  3. public int Id { get; set; }
  4. public string FirstName { get; set; }
  5. public string LastName { get; set; }
  6. public AdditionalData AdditionalData { get; set; } //Save this object as Json
  7. }
  8. public class AdditionalData
  9. {
  10. public List<string> PhoneNumbers { get; set; }
  11. //other props
  12. }
  13. protected override void OnModelCreating(ModelBuilder modelBuilder)
  14. {
  15. modelBuilder.Entity<Person>().OwnsOne(
  16. p => p.AdditionalData, options =>
  17. {
  18. options.ToJson(); //will save the object as Json into database
  19. });
  20. }

因此,例如,如果你想更新电话号码,你可以这样做:

  1. var perzon = await _dbContext.Persons.FirstOrDefaultAsync(x=> x.Id == id);
  2. //update street
  3. author.AdditionalData.PhoneNumbers.Add("123467899");
  4. _dbContext.Update(person);
  5. await _dbContext.SaveChangesAsync(); // will update the json
展开查看全部

相关问题