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

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

我考虑将一些信息作为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:

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
}

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

{
  phoneNumbers:["123456789","789456123"],
  groups:[{name:"g1", description:"blah"}, {name:"g2", description:"blah2"}]
}

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

void AddPhoneNumber(int personId, string phoneNumber);

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

context.Database.ExecuteSqlCommand("UPDATE Person
SET additionalData = JSON_MODIFY(additionalData,"append  $.phoneNumbers", @phoneNumber)
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属性:

public class Person
{
    public int Id { get; set; }
    public string FirstName { get; set; }
    public string LastName { get; set; }
    public AdditionalData AdditionalData { get; set; } //Save this object as Json
}

public class AdditionalData
{
    public List<string> PhoneNumbers { get; set; }
    //other props 
}

protected override void OnModelCreating(ModelBuilder modelBuilder)
{
    modelBuilder.Entity<Person>().OwnsOne(
        p => p.AdditionalData, options =>
        {
            options.ToJson(); //will save the object as Json into database
        });
}

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

var perzon = await _dbContext.Persons.FirstOrDefaultAsync(x=> x.Id == id);

//update street
author.AdditionalData.PhoneNumbers.Add("123467899");

_dbContext.Update(person);
await _dbContext.SaveChangesAsync(); // will update the json

相关问题