Как не запускать PropertyChanged при получении объекта из базы данных?

У меня есть приложение WPF, в котором я использую базовый класс. Я также использую Fody PropertyChanged и EF 6.1.3. Я пытаюсь изменить свойство SaveNeeded всякий раз, когда изменяется какое-либо свойство. Поэтому я пишу этот класс:

 public class Foo : INotifyPropertyChanged
{
    public Foo()
    {
        PropertyChanged += Foo_PropertyChanged;
    }

    public event PropertyChangedEventHandler PropertyChanged;

    public string GivenNames { get; set; }

    public int Id { get; set; }

    [NotMapped]
    public bool SaveNeeded { get; set; }

    private void Foo_PropertyChanged(object sender, PropertyChangedEventArgs e)
    {
        SaveNeeded = true;
    }
}

Когда я создаю новый Foo, а затем меняю какое-то свойство, он работает так, как я думаю. Но когда я пытаюсь получить Foo из базы данных с помощью EF, запускается событие PropertyChanged. Любые предложения, как получить Foo из базы данных и не запускать PropertyChanged?

Благодарю вас!!


person Pavol    schedule 16.06.2017    source источник
comment
Когда вы получаете объект из базы данных, EF создает этот объект для вас, а затем устанавливает его свойства. Вот почему событие запускается.   -  person 3615    schedule 16.06.2017
comment
Да, я понял.. но есть ли какое-то обходное решение?   -  person Pavol    schedule 16.06.2017
comment
Я не знаю ни одного. INPC обычно используется для ViewModels, но EF возвращает сущности предметной области. Вам следует изменить подход. Вместо того, чтобы добавлять INPC к сущностям, вы должны создать ViewModels, которые представляют сущности, и добавить туда INPC. А для преобразования сущностей в ViewModels вы можете использовать что-то вроде automapper.   -  person 3615    schedule 16.06.2017
comment
Automapper использует ту же технику, что и EF.. создает объект, а затем устанавливает его свойства.   -  person Pavol    schedule 16.06.2017
comment
Да, ты прав. Вы по-прежнему можете создавать ViewModels, передавая параметры через конструктор, без автосопоставления, но это довольно утомительно...   -  person 3615    schedule 16.06.2017
comment
Как указывалось ранее, я думаю, что у вас должны быть классы модели представления и классы модели базы данных (которые не будут реализовывать INPC). Другим решением является использование вашей собственной или «стандартной» реализации INPC, где вы можете изменить поведение своего метода, который запускает INPC, поэтому, когда, скажем, установлен какой-либо флаг, например «isReadingDataFromDB», вы не поднимете INPC, а только назначенное поле позади это свойство. После загрузки всех данных вам, вероятно, придется запустить несколько INPC самостоятельно, чтобы обновить пользовательский интерфейс, но это будет сделано только один раз.   -  person Lukasz Cokot    schedule 16.06.2017
comment
если вы хотите использовать и автоматический инжектор кода, то вы застряли в своем поведении, fody позволяет вам украсить с помощью DoNotNotifyAttribute, если есть свойство, которое вы хотите никогда не обновлять, но в противном случае, как @3615 говорит, что вы не следуете передовой практике, что хорошо, если это работает для вы, но означает, что вы должны принять побочные эффекты, я пробовал автоматические инъекторы, и я обнаружил, что количество раз, когда они не работают, настолько велико, что они больше хлопот, чем они того стоят   -  person MikeT    schedule 16.06.2017


Ответы (1)


Хорошо, спасибо за предложения, я сделал это так:

  public class Foo : INotifyPropertyChanged
{
    public event PropertyChangedEventHandler PropertyChanged;

    public string GivenNames { get; set; }

    public int Id { get; set; }
}

 public class FooViewModel : Foo
{

    public bool SaveNeeded { get; set; }

    public void NoticeChanges()
    {
        PropertyChanged += FooViewModel_PropertyChanged;
    }

    private void FooViewModel_PropertyChanged(object sender, PropertyChangedEventArgs e)
    {
        SaveNeeded = true;
    }
}

Итак, я беру Foo из базы данных, сопоставляю свойства с помощью Automapper, а затем вызываю NoticeChanges.

person Pavol    schedule 16.06.2017