Платформа сущностей не обнаруживает изменения свойств jsonb в c# - PullRequest
0 голосов
/ 26 мая 2020

Я использую Entity Framework Core с npg sql postgresql для Entity Framework Core. и я работаю с. net core 3

Мой вопрос: когда я пытаюсь обновить элемент MyTableRelated из MyTableClass и сохраняю контекст в базе данных, никаких изменений не обнаруживается.

Например, предположим, что у нас есть следующие классы:

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();

Это работает, и запись сохраняется в базе данных.

Теперь где-то в приложении я хочу получить доступ к этой записи и изменить значения в Data:

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

Как можно реализовать что-то подобное?

1 Ответ

1 голос
/ 28 мая 2020

Автоматическое обнаружение c изменений будет означать, что EF Core будет делать снимок документа JSON при загрузке свойства (дублируя все дерево), а затем выполнять полное структурное сравнение исходного и текущего дерева всякий раз, когда SaveChanges называется. Поскольку это может быть очень сложно с точки зрения производительности, по умолчанию это не делается. документы EF о том, как это сделать . Я открыл проблему в репозитории поставщика Npg sql на случай, если кто-то захочет внести свой вклад.

По соображениям производительности я бы рекомендовал вручную отмечать свойства при их изменении, аналогично к тому, что вы сделали. Обратите внимание, что вы помечаете весь экземпляр объекта как измененный, поэтому все свойства будут сохранены. Вы можете использовать следующее, чтобы отметить свойство JSON:

ctx.Entry(entry).Property(e => e.SomeJsonProperty).IsModified = true;
...