[英]Self referencing loop in Entity Framework Core models when using InverseProperty
[英]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 更改跟踪代理,这些代理基本上为您实现了所有INotifyPropertyChanging
和INotifyPropertyChanged
功能。 但是您需要将所有属性设为虚拟,并且还可以访问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.