Почему метод Entity Framework Core 2 Attach () не позволяет отслеживать последующие изменения? - PullRequest
0 голосов
/ 19 октября 2018

Я портирую приложение на EF Core 2 и хочу сделать много частичных обновлений объектов.Но я не хочу сначала запрашивать эти объекты (я уже знаю, что они там есть, и мне все равно, каковы предыдущие значения свойств, которые я изменяю; запрос их - пустая трата поездки туда и обратно в БД).

В EF6 я просто создаю объект с соответствующим значением ключа, присоединяю его, делаю свои изменения и сохраняю, и он генерирует обновление в SQL с использованием отслеженных изменений.Но в EF Core 2 это не работает;состояние субъекта остается неизменным.Я знаю, что могу вручную сказать трекеру, что я изменил определенные свойства, но это грязно по двум причинам: код, который должен запрашивать объекты перед частичным обновлением , не должен делать это, поэтомусбивает с толку, а также этот шаблон заставил бы меня указывать каждое свойство дважды, что очень мокро.

Придуманный пример, предполагая, что MyDbContext наследует DbContext, сгенерированный из Scaffold-DbContext:

//This is a model class for a table (id uniqueidentifier PRIMARY KEY, data int)
public partial class Record
{
    public Guid id { get; set; }
    public bool data { get; set; }
}

Некоторый кодэто не приводит к обновлениям базы данных:

using (var db = new MyDbContext()) {
    var rec = new Record {
       id = new Guid('bc372788-5a96-4ada-a2e0-c604d1abed92')
    }
    db.Attach(rec);
    rec.data = false;
    db.SaveChanges();
}

Некоторый код, который вызывает обновление, но становится очень грязным, если изменилось более одного свойства:

using (var db = new MyDbContext()) {
    var rec = new Record {
       id = new Guid('bc372788-5a96-4ada-a2e0-c604d1abed92'),
       data = false
    }
    db.Attach(rec).Property(x => x.data).IsModified = true;
    db.SaveChanges();
}

Для большего акцентанекоторый код, который делает бесполезный запрос, но обновляет БД так, как я хочу:

using (var db = new MyDbContext()) {
    var rec = db.Record.Single(x => x.id == new Guid('bc372788-5a96-4ada-a2e0-c604d1abed92'));
    rec.data = false;
    db.SaveChanges();
}

Есть ли способ сделать это, чтобы мне не нужно было делать запрос для существующей записи перед обновлениемэто, но также и то, что EF Core 2 отслеживает изменения, которые я делаю в записи?

1 Ответ

0 голосов
/ 19 октября 2018

Это не работает, потому что я дурак.Значение CLR по умолчанию для bool равно false, и поэтому недавно созданный объект уже имеет data = false.Отслеживание изменений запускается и, конечно, обнаруживает, что оно все еще ложно, и не генерирует никаких изменений.

Одно из решений - установить значение, отличное от значения по умолчанию, чтобы оно выглядело измененным:

using (var db = new MyDbContext()) {
    var rec = new Record {
       id = new Guid('bc372788-5a96-4ada-a2e0-c604d1abed92'),
       data = true
    }
    db.Attach(rec);
    rec.data = false;
    db.SaveChanges();
}

Другой вариант - использовать обнуляемый тип в классе (при необходимости), а другой - просто объявить, что свойство модифицировано с помощью .IsModified, как указано выше.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...