实体框架未检测到C#中的jsonb属性更改

问题描述 投票:0回答:1

我正在将Entity Framework Core和npgsql postgresql用于Entity Framework Core。并且我正在使用.net core 3

我的问题是,当我尝试从MyTableClass更新MyTableRelated元素并将上下文保存到数据库时,未检测到任何更改。

例如,假设我们有以下类:

public class MyTableClass
{
    public int Id { get; set; }

    [Column(TypeName = "jsonb")]
    public virtual List<MyTableRelated> Data { get; set; }
}

public class MyTableRelated
{
    public int Id { get; set; }

    public string prop1 { get; set; }

    public string prop2 { get; set; }
}

和一些类似的代码(这不是实际的代码,仅是为了获得想法):

var context = dbContext;

var newMyTableClass = new MyTableClass() {
    Id = 1;
};

var newMyTableRelated = new MyTableRelated(){
    Id=1;

    prop1 = "";

    prop2 = "";
}

newMyTableClass.Data.Add(newMyTableRelated);

context.SaveChanges();

这有效,并且该条目保存在数据库中。

现在在应用程序的某处,我想访问该条目并更改数据上的值:

var context = dbContext;

var updateMyTableClass = context.MyTableClass.FirstOrDefault(x => x.Id == 1);

var tableRelated = updateMyTableClass.Data.FirstOrDefault(y => y.Id == 1);

tableRelated.prop1 = "prop1";

tableRelated.prop2 = "prop2";

context.SaveChanges();

我想这会改变数据库的值,就像其他类型的属性一样。但是什么也没发生。

我发现的解决方案正在使用此:

var entry = context.Entry(updateMyTableClass);
if (entry.State == EntityState.Unchanged)
{
   entry.State = EntityState.Modified;
}

这更多是针对该情况的临时解决方案。

然后我们如何使EF自动检测jsonb属性的更改?

有人指着我,我应该看看科斯粒度锁。https://www.martinfowler.com/eaaCatalog/coarseGrainedLock.html

如何实现?

c# entity-framework asp.net-core npgsql asp.net-core-3.0
1个回答
0
投票

自动更改检测意味着EF Core在加载属性(复制整个树)时将为JSON文档拍摄快照,然后在调用SaveChanges时对原始树和当前树进行完整的结构比较。由于这可能会非常麻烦,因此默认情况下不会进行此操作。

但是,如果您愿意,可以创建一个值比较器来精确实现此功能-see the EF docs on how to do that。如果有人希望提供帮助,请在Npgsql提供程序仓库上单击I've opened an issue

出于性能方面的考虑,我建议您在属性更改时手动对其进行标记,这与您所做的类似。请注意,您将整个实体实例标记为已更改-因此将保存所有属性。您可以使用以下内容仅标记JSON属性:

ctx.Entry(entry).Property(e => e.SomeJsonProperty).IsModified = true;
© www.soinside.com 2019 - 2024. All rights reserved.