Scolo Ответов: 1

UWP - entity framework core (dbcontext) привязка к dbset не обновляется


Всем привет,

Я работаю в UWP с EntityFrameWorkCore и SQLite.
Я пытаюсь привязаться к своему DbSet, но он не обновляется.

Я мог бы заставить свою привязку работать, когда я изменяю имя свойства, оно обновляется. Но ListView не обновляется, когда я добавляю/удаляю элементы в/из своего DbSet.

Вот мой код:

Вот и занятия. Обратите внимание, что привязка к DbSet при добавлении/удалении элементов не работает.
Но когда я изменяю имя, оно работает и обновляется.

public class ContactsContext : DbContext
{
    public DbSet<Contact> Contacts { get; set; }

    protected override void OnConfiguring(DbContextOptionsBuilder optionsBuilder)
    {
        optionsBuilder.UseSqlite("Data Source=blogging.db");
    }
}

public class Contact : INotifyPropertyChanged
{
    private string _Name;

    public event PropertyChangedEventHandler PropertyChanged;

    [Key]
    public string Name
    {
        get { return _Name; }
        set
        {
            if (_Name != value)
            {
                _Name = value;
                NotifyPropertyChanged("Name");
            }
        }
    }

    public void NotifyPropertyChanged(string propertyName)
    {
        if (PropertyChanged != null)
        {
            PropertyChanged(this,
                new PropertyChangedEventArgs(propertyName));
        }
    }

}


<ListView Name="myListView" ItemsSource="{Binding}"
HorizontalAlignment="Center" VerticalAlignment="Center">
    <ListView.ItemTemplate>
        <DataTemplate x:DataType="Data:Contact">
            <TextBlock Text="{x:Bind Name}"/>
        </DataTemplate>
    </ListView.ItemTemplate>
</ListView>


private void Page_Loaded(object sender, RoutedEventArgs e)
{
    using (ContactsContext db = new ContactsContext())
    {
        myListView.ItemsSource = db.Contacts;
    }
}

private void Adder_Click(object sender, RoutedEventArgs e)
{
    using (ContactsContext db = new ContactsContext())
    {
        db.Contacts.Add(new Contact { Name = myTextBox.Text });
        db.SaveChanges();
    }
}


Что я уже пробовал:

Я уже пытался добавить
INotifyPropertyChanged
к моему классу DataContext, но никакого эффекта.

public class ContactsContext : DbContext
    {
        private DbSet<Contact> _Contacts { get; set; }
        
        public event PropertyChangedEventHandler PropertyChanged;

        public string Contacts
        {
            get { return _Contacts; }
            set
            {
                    _Contacts = value;
                    NotifyPropertyChanged("Contacts");
            }
        }

        public void NotifyPropertyChanged(string propertyName)
        {
            if (PropertyChanged != null)
            {
                PropertyChanged(this,
                    new PropertyChangedEventArgs(propertyName));
            }
        }


        protected override void OnConfiguring(DbContextOptionsBuilder optionsBuilder)
        {
            optionsBuilder.UseSqlite("Data Source=blogging.db");
        }
    }


Попытался создать другой класс, который был ObservableCollection для перечисления контактов. но
1) это выглядело очень сложным решением, и я думаю, что должно быть что-то проще.
2) он работал нормально, но у меня были некоторые проблемы при сохранении изменений (db.SaveChanges).

Кто-то жил через это и имеет какое-то фантастическое решение?
спасибо.

1 Ответов

Рейтинг:
2

Richard Deeming

Ваш Page_Loaded метод создает один экземпляр вашего контекста, загружает данные и привязывает их к вашему списку. Ваш Adder_Click метод создает совершенно отдельный экземпляр в вашем контексте, добавляет новую запись, и сохраняет изменения.

Изменения, внесенные в один экземпляр вашего контекста, не будут видны другому экземпляру вашего контекста. Вместо этого вам нужно будет создать один экземпляр контекста и использовать его для всех операций на странице.

Кроме того, в EF6 вам нужно будет использовать набор .Load() метод и .Local свойство для привязки к элементу управления WPF. Вам нужно будет проверить, так ли это по-прежнему с EF Core и UWP:
Привязка данных Entity Framework с помощью WPF[^]


Scolo

Привет, Ричард, спасибо за ответ :)

Но я могу соглашаться и не соглашаться?
Это не объясняет тогда почему если я это сделаю:

db.Contacts.FirstOrDefault().Name = "updated";

он обновляется в виде списка.

Я немного поиграл с ними .Local and .Load() и у меня возникла другая проблема. Я мог бы очень хорошо обновить ListView, но когда я попробовал .SaveChanges (), он ничего не сохранил.

Richard Deeming

Вы проводите эту линию против DbContext экземпляр, который вы использовали для привязки своего списка, или новый DbContext например?

Scolo

Оба,
Я попробовал с

using (ContactsContext db = new ContactsContext())
внутри я сделал свою привязку и использовал местную, никакой помощи.
Но также попробовал объявить частное в самом начале
private ContactsContext myContext = new ContactsContext();
и использовать его все время. Ни один из них не работал (с частным я пробовал также статику, никакой помощи).

Я начинаю думать, что это просто что-то не работает в UWP.
Как вы можете видеть в документах Microsoft, они говорят только о привязке к WPF и WinForms.

Scolo

Я все еще застрял с этим.
Я следую учебнику WPF, но он совсем не помогает в UWP.

Я пытаюсь связать вот так:
Скрыть   скопировать код

db.Contacts.Load(); myListView.ItemsSource = db.Contacts.Local;

и он все еще не обновляется, когда я позже добавляю/удаляю элементы.

К сожалению в магазина нет Скрыть   скопировать код
Items.Refresh()
или что-то похожее.
Так что этот учебник не очень помогает.