当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
要将控件绑定到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
跟踪的所有Unchanged
、Modified
和Added
对象。从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();
}
}
如果我找到更好的解决方案,我会告诉你的。