ef.net 核心,属性而不是字段

ef.net core, properties instead of fields

因此,我们正在将一个旧的 wpf 应用程序移植到 .net core wpf 中。作为工作的一部分,我们还将数据层移动到 EF.net core

  1. 由于我们使用 Prism MVVM,在 DI 服务上下文中,我们保留了一个实时数据上下文,它跟踪用户通过 wpf 前端和通过服务显示和编辑的实体。
  2. 为了实现 "undo" 功能,我们使用以下方法跟踪对象 entity.HasChangeTrackingStrategy(ChangeTrackingStrategy.ChangingAndChangedNotificationsWithOriginalValues);

在编辑时,对象得到更新,在 Reload() 时,它从跟踪的原始值恢复。就对象而言,操作正常,但是,wpf 方面的工作不正常。 ef.net 核心似乎是 wpf 应用程序的一个非常不适应的公民,假设它是 INotifyPropertyChanged 机制的唯一受益者。当然,这对于 WPF 来说一点也不正确。

  1. EF.net 似乎在加载、重新加载等时不使用属性。它直接作用于底层字段。因此,NotifyPropertyChanged 永远不会触发,因此网格永远不会用新数据刷新,比如说 dbContext.Entry(c).Reload();。那么问题 #1,有没有办法强制 ef.net 使用属性而不是字段?
  2. INotifyPropertyChanged 的 ef.net 实施似乎有缺陷。如果您在 属性 上调用 PropoertyChanged 事件而不实际更改它,它会将实体标记为 Modified,即使它可以轻松比较原始值和当前值。这禁止我们手动引发 属性 changed 事件来控制 WPF 渲染。不知道如何解决这个问题,或者它是否可以解决,因为它只适用于这个跟踪策略。我愿意接受任何关于如何通知 WPF 元素而不激怒 ef.net.
  3. 的建议
  4. 确定对象的状态是相当复杂的操作,涉及 dbContext.Entry(entry).State,它存在于 DataContext 层次结构中的任何 WPF 绑定之外。它几乎不可能绑定状态(例如更改脏条目的背景或显示保存按钮等)。我们 "solved" 它通过从 NotifySetterObject 基础 class 继承我们所有的实体 classes 来处理 INotify* 实现并保留 [NotMapped] bool IsDirty 标志。不用说,我非常不喜欢这个,保留两个未链接的状态标志听起来像是等待发生的事故。我想知道您是否遇到过类似的问题,以及您是否设计了更好、更理智的解决方案。

EF.net 似乎经历了框架 ef.net 的重大变革,仅适用于分离的上下文场景(如 asp.net)。我们是不是在浪费时间试图让这双鞋适合 wpf?我们是否应该专注于更适合实时环境的不同 OR 引擎?

在尝试回答您的问题之前,让我指出一些事情:

  1. 您使用的是 EF Core 3.0,目前处于预览(测试版)阶段,因此很多功能可能无法按预期运行。

  2. 如果 ef.net 你指的是 EF6,即你正在移植的旧项目使用的是 EF6,那么切换到 EF Core 并不是很有必要 - EF6 也是 getting .Net Core support - a preview version is available here .

现在关于您的具体问题:

  1. EF Core 可以 使用属性、字段或两者。这可以通过 fluent API 在上下文、实体和 属性 级别进行配置。只是 EF Core 3.0 默认值发生了变化——您可以在 Breaking Changes - Backing fields are used by default 中看到这一点。 link 还显示了如何使用

    获得所需的行为
    .UsePropertyAccessMode(PropertyAccessMode.FieldDuringConstruction)
    

在模型(所有实体)、实体(所有实体属性)或 属性(特定实体 属性)构建器上。

  1. ChangeTrackingStrategy 文档中解释了该行为:

Original values are recorded when the entity raises the PropertyChanging. Properties are marked as modified when the entity raises the PropertyChanged event.

这是设计使然,因此您无能为力。但解决 #1 消除了手动引发 PropertyChanged 事件的需要,双向绑定似乎完美无缺。

  1. 我不太确定你到底来这里是为了什么。但是从 v2.1 开始,EF Core 提供了 2 State change events on ChangeTracker - Tracked and StateChanged, which (especially the second) can be used to provide state change notifications. But the actual mechanism for that is left for you. For instance, you can use EF Core 2.1+ entity constructor service injection 特性来将 DbContext 注入到实体中,实体又可以订阅 StateChanged 事件并为自己未映射的引发 PropertyChanged State 属性 等