繁体   English   中英

WPF 使用 Entity Framework Core 模型时数据网格未更新

[英]WPF datagrid not updating when using Entity Framework Core Models

我有一个 WPF window 来显示培训 class 的详细信息,以及数据网格中的参与者列表。

我正在使用 Entity Framework Core,我的训练 class model 看起来像这样

public partial class TrainingClass
{
    public TrainingClass()
    {
        TrainingAttendees = new HashSet<TrainingAttendee>();
    }

    public int ClassId { get; set; } // PK
    public DateTime DateFrom { get; set; }
    public DateTime DateTo { get; set; }
    public string CourseName { get; set; }

    public virtual ICollection<TrainingAttendee> TrainingAttendees { get; set; }
}

在我的TrainingClassDetailsViewModel中,我有一个按钮可以打开对话框 window,用户可以在其中输入与会者详细信息并单击“保存”按钮

public void AddAttendee(object parameter)
{
    TrainingAttendee attendee = new TrainingAttendee()

    TrainingAttendeeViewModel vm = new TrainingAttendeeViewModel(attendee);
    _windowService.ShowDialog<TrainingAttendeeEditor>(vm);

    if (vm.SaveClicked)
    {
        _trainingClass.TrainingAttendees.Add(attendee);
    }
}

这会添加新的参与者,因此 EF Core 可以在调用SaveChanges时更新数据库,但这不会更新数据网格。

我知道我需要使用ObservableCollection ,它使用INotifyPropertyChanged 如果我实施以下并使用Attendees.Add(attendee); 相反,这将更新数据网格,但不会更新数据库。

private ObservableCollection<TrainingAttendee> _attendees;
public ObservableCollection<TrainingAttendee> Attendees
{
    get => _attendees;
    set
    {
        if (_attendees != value)
        {
            _attendees = value;
            ApplyPropertyChange();
        }
    }
}

...

_attendees = new ObservableCollection<TrainingAttendee>(_trainingClass.TrainingAttendees);

我能得到的唯一工作方法是同时执行_trainingClass.TrainingAttendees.Add(attendee); Attendees.Add(attendee); . 但我发现管理 2 个列表很奇怪。 我需要调用我自己的ApplyPropertyChanged

我将如何最好地实现这一点?

您可以使用ObservableCollection<T>作为集合导航属性的后备存储(代替当前的HashSet<T> )。 或者甚至更好,EF Core 提供了ObservableHashSet<T> class。例如

using Microsoft.EntityFrameworkCore.ChangeTracking; // <-- required

public partial class TrainingClass
{
    public TrainingClass()
    {
        TrainingAttendees = new ObservableHashSet<TrainingAttendee>(); // <--
    }

    //...

    public virtual ICollection<TrainingAttendee> TrainingAttendees { get; set; }
}

有关详细信息,请参阅官方 EF Core 文档中的通知实体部分和整个更改跟踪主题。

此外,如果您使用的是 EF Core 5.0 或更高版本,则可以利用 EF Core 更改跟踪代理,这些代理基本上为您实现了所有INotifyPropertyChangingINotifyPropertyChanged功能。 但是您需要将所有属性设为虚拟,并且还可以访问DbContext并使用CreateProxy扩展方法而不是new来创建新的实体实例。

这是一个很好的例子,为什么你不应该直接绑定到自动生成的 (EF) model 类。

您应该绑定到视图模型或包装类,并在您的实体对象与这些对象之间进行转换/映射。

在您的AddAttendee方法中,您将像您当前所做的那样将实体添加到上下文中,但还将视图模型/包装器添加到数据绑定的ObservableCollection<T>中:

if (vm.SaveClicked)
{
     //1. add to EF context
    _trainingClass.TrainingAttendees.Add(attendee);
     //2. Add to source data-bound collection
    vm.SourceCollection.Add(new Wrapper(attendee));
}

您会在此处找到“包装”model 的视图 model class 的示例。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM