当EF';的实体值发生更改

本文关键字:实体 EF | 更新日期: 2023-09-27 18:28:19

我是实体框架的新手,我正在努力学习它。

我试图修改官方文件上的一项练习:我想要一份父亲和儿子的名单。每个儿子都必须有一个从组合菜单中选择的父亲。

现在我可以这么做了,但是,如果我添加一个父亲,我不会在父亲列表或组合框中看到它。如果我添加一个儿子,我在儿子列表中看不到该儿子。

如果我关闭并重新打开程序,我会正确地看到之前添加的父亲和儿子。

如何自动升级组合框和列表视图中的数据?

我不想调用函数来刷新,我想在更改数据库中的某些内容时自动进行刷新。

我的项目由3个文件组成:

主窗口.xaml

<Window x:Class="EF7Fam.MainWindow"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
        xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
        xmlns:local="clr-namespace:EF7Fam"
        mc:Ignorable="d"
        Loaded="Page_Loaded"
        Title="MainWindow" Height="350" Width="550">
    <Grid>
        <StackPanel Orientation="Horizontal">
            <StackPanel Width="263" Margin="3 0 3 0">
                <TextBox Name="NewFT"></TextBox>
                <Button Click="Add_Click">Add</Button>
                <ListView Name="Fathers">
                    <ListView.ItemTemplate>
                        <DataTemplate>
                            <TextBlock Text="{Binding Name, UpdateSourceTrigger=PropertyChanged}" />
                        </DataTemplate>
                    </ListView.ItemTemplate>
                </ListView>
            </StackPanel>
            <StackPanel Width="263" Margin="3 0 3 0">
                <TextBox Name="NewSN"></TextBox>
                <ComboBox Name="FT" DisplayMemberPath="Name" SelectedValuePath="FTId"/>
                <Button Click="Add_SN_Click">Add</Button>
                <ListView Name="Sons">
                    <ListView.ItemTemplate>
                        <DataTemplate>
                            <TextBlock Text="{Binding Name, UpdateSourceTrigger=PropertyChanged}" />
                        </DataTemplate>
                    </ListView.ItemTemplate>
                </ListView>
            </StackPanel>
        </StackPanel>
    </Grid>
</Window>

主窗口.xaml.cs

using Microsoft.Data.Entity;
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Linq;
using System.Text;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Data;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Imaging;
using System.Windows.Navigation;
using System.Windows.Shapes;
namespace EF7Fam
{
    /// <summary>
    /// Logica di interazione per MainWindow.xaml
    /// </summary>
    public partial class MainWindow : Window
    {
        public MainWindow()
        {
            InitializeComponent();
            using (var db = new Family())
            {
                db.Database.Migrate();
            }
        }
        private void Page_Loaded(object sender, RoutedEventArgs e)
        {
            using (var db = new Family())
            {
                Fathers.ItemsSource = db.Fathers.ToList();
                Sons.ItemsSource = db.Sons.ToList();
                FT.ItemsSource = db.Fathers.ToList();
            }
        }
        private void Add_Click(object sender, RoutedEventArgs e)
        {
            using (var db = new Family())
            {
                var ft = new Father { Name = NewFT.Text };
                db.Fathers.Add(ft);
                db.SaveChanges();
            }
        }
        private void Add_SN_Click(object sender, RoutedEventArgs e) 
        {
            using (var db = new Family())
            {
                var sn = new Son { Name = NewSN.Text, FTId = Int32.Parse(FT.SelectedValue.ToString()) };
                db.Sons.Add(sn);
                db.SaveChanges();
            }
        }
    }
}

型号.cs

using System;
using Microsoft.Data.Entity;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.ComponentModel.DataAnnotations;
using System.ComponentModel;
using System.ComponentModel.Design;
using System.Runtime.CompilerServices;
namespace EF7Fam
{
    public class Family : DbContext
    {
        public DbSet<Father> Fathers { get; set; }
        public DbSet<Son> Sons { get; set; }
        protected override void OnConfiguring(DbContextOptionsBuilder optionsBuilder)
        {
            optionsBuilder.UseSqlite($"Filename=Family.db");
        }
        protected override void OnModelCreating(ModelBuilder modelBuilder)
        {
            modelBuilder.Entity<Father>()
                .Property(b => b.Name)
                .IsRequired();
        }
    }
    public class Father : INotifyPropertyChanged
    {
        [Key]
        public int FTId { get; set; }
        public string Name { get; set; }
        public List<Son> Sons { get; set; }
        public event PropertyChangedEventHandler PropertyChanged;
        public void OnPropertyChanged([CallerMemberName] string propertyName = null)
        {
            if (PropertyChanged != null)
                PropertyChanged(this, new PropertyChangedEventArgs(propertyName));
        }
    }

    public class Son : INotifyPropertyChanged
    {
        [Key]
        public int SNId { get; set; }
        public string Name { get; set; }
        public int FTId { get; set; }
        public Father Father { get; set; }
        public event PropertyChangedEventHandler PropertyChanged;
        public void OnPropertyChanged([CallerMemberName] string propertyName = null)
        {
            if (PropertyChanged != null)
                PropertyChanged(this, new PropertyChangedEventArgs(propertyName));
        }
    }
}

我在这个网站和网上看了很多次,但都没有找到解决方案。

,如果有人能帮助我,让我知道我做错了什么,我将非常感激

谢谢,再见,

Enrico

当EF';的实体值发生更改

要将控件绑定到DbSets,需要执行以下操作:

private void Page_Loaded(object sender, RoutedEventArgs e)
{
        using (var db = new Family())
        {
            db.Fathers.Load();
            Fathers.ItemsSource = db.Fathers.Local;
            db.Sons.Load();
            Sons.ItemsSource = db.Sons.Local;
            FT.ItemsSource = db.Fathers.Local;
        }
}

调用Load方法,您将把现有对象加载到内存中,DbSet<TEntity>.Local属性将为您提供一个ObservableCollection<TEntity>,其中包含DbContext当前为给定DbSet跟踪的所有UnchangedModifiedAdded对象。从ObservableCollection添加或移除也将在DbSet上执行相应的Add/Remove

这样,如果在执行视图中所需的所有操作后需要保存更改,则可以定义一个命令或覆盖视图中按钮的单击事件,并调用上下文的SaveChanges方法:

  private void SaveChanges_Click(object sender, RoutedEventArgs e) 
  {
        using (var db = new Family())
        {
            db.SaveChanges();
        }
  }

更新

现在我看到你正在使用EF7,事实是我不知道这个版本中的所有更改,但我可以告诉你,有很多,也许这个属性还没有实现。我发现了一个关于这个问题的问题,但还没有得到回答。

在文档中挖掘更多内容,我想我找到了一个解决方案,但事实上我不喜欢它,但它可以工作,直到Load属性出现。根据EF文件,您可以这样做:

private void Add_Click(object sender, RoutedEventArgs e)
{
        using (var db = new Family())
        {
            var ft = new Father { Name = NewFT.Text };
            db.Fathers.Add(ft);
            db.SaveChanges();
            Fathers.ItemsSource = db.Fathers.ToList();
        }
 }

如果我找到更好的解决方案,我会告诉你的。