You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

在Prism MVVM架构中使用Entity Framework:如何将自增ID同步到CollectionViewSource?

解决Prism MVVM架构下EF Core自增ID同步到DataGrid的问题

我完全懂你的痛点——在把EF Core WPF入门教程适配到Prism MVVM架构时,SaveChanges后自增ID无法同步到DataGrid,还不想丢失排序过滤功能,这种卡壳的感觉太熟悉了。咱们一步步来拆解问题,找到最符合MVVM规范的优雅解法。

问题根源分析

其实EF Core在调用SaveChanges()后,已经把自增ID更新到了内存中的实体对象里,但WPF的DataGrid绑定的CollectionViewSource没感知到这个变化——核心原因是你的Category实体类没有实现属性变更通知(也就是INotifyPropertyChanged)。你提到过尝试让它继承BindableBase但没成功,应该是属性的写法不对。

最优解:让实体实现属性变更通知

Prism的BindableBase已经封装了INotifyPropertyChanged的逻辑,咱们只要正确用它包装实体的属性就行:

修改Category实体类

namespace EfTestPrism;
public class Category : BindableBase
{
    private int _categoryId;
    public int CategoryId
    {
        get => _categoryId;
        set => SetProperty(ref _categoryId, value);
    }

    private string _name = string.Empty;
    public string Name
    {
        get => _name;
        set => SetProperty(ref _name, value);
    }
}

EF Core完全支持这种写法,它会自动更新实体的属性值,而SetProperty会触发PropertyChanged事件,让UI自动刷新对应的DataGrid单元格。

简化ViewModel的Save方法

现在你不需要再重新赋值CategoriesCollection,也不需要依赖View的回调委托了,直接调用SaveChanges()就行:

private void Save()
{
    context.SaveChanges();
    // 啥额外操作都不用加!
}

为什么之前的方案无效?

咱们来复盘一下你试过的无效方案,搞清楚背后的原因:

  • 调用RaisePropertyChanged(nameof(CategoriesCollection)):没用,因为集合本身没变化,只是集合内的实体属性变了,这个通知只会告诉UI“整个集合换了”,不会触发单个项的刷新。
  • 遍历调用RaisePropertyChanged:因为原来的Category没实现INotifyPropertyChanged,这些调用根本不会向UI发送任何变更通知。
  • 手动修改ID再恢复:这种方式不仅容易引发异常,而且不符合WPF的属性变更通知机制,UI没法正确感知变化。

关于你找到的委托回调方案

你后来实现的ViewModel调用View回调的方案确实可行,而且代码量少,但它的问题是让ViewModel和View产生了耦合——ViewModel知道了View的具体实现(DataGrid的Items.Refresh()),这其实违背了MVVM“ViewModel不依赖View”的核心原则。如果后续你换了其他控件展示数据,这个回调逻辑就得跟着改。

而让实体实现属性变更通知的方式,完全遵循了MVVM的解耦原则,同时完美保留了DataGrid的排序、过滤状态,是最优雅的长期解决方案。

内容的提问来源于stack exchange,提问作者robsn

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.01 03:02:34