我在由 SQL CE 数据库支持的 WPF MVVM 应用程序中使用 Entity Framework 和代码优先方法。我正在尝试设计一个模型类,它可以简单地更新其一个属性值以响应其另一个属性值的更改。基本上,我正在寻找一种方法来定义在 EF 初始化实例后“ self 跟踪”的 poco。如果答案涉及放弃 Code First,那么也许这是唯一可行的途径(不确定)。一个基本示例:
class ThingModel
{
public int Id { get; set; }
public bool OutsideDbNeedsUpdate { get; set; }
private string _foo;
public string Foo
{
get { return _foo; }
set
{
if (_foo != value)
{
_foo = value;
OutsideDbNeedsUpdate = true;
}
}
}
}
但是,上述问题是,每当 DbContext 在运行时初始化实例并设置字段时,我的类都会过早地设置依赖字段作为响应。换句话说,我正在寻找一种简单的模式,允许我的 poco 类仅在 EF 完成初始化实例上的字段后执行此特殊的更改跟踪。
我意识到我可以做类似解决方案 here 的事情 但我的业务案例要求这种特殊的更改跟踪与 EF 更改跟踪分离,换句话说,我需要具有 SaveChanges 的能力,无论上面的 HasChanges 属性的状态如何。这是因为我希望能够定期检查实体上的 HasChanges 属性,然后更新外部数据库中的相关值(与支持 EF DbContext 的数据库不同),并且 EF DB 之间可能会发生许多更改/保存推送到外部数据库。因此,我希望将标志与记录保留在我的数据库中,并在定期更新外部数据库时将其重置为 false。
最佳答案
编辑后我认为您可以使用 ObjectMaterialized event 。
This event is raised after all scalar, complex, and reference properties have been set on an object, but before collections are loaded.
将其放入 DbContext
的构造函数中:
((IObjectContextAdapter)this).ObjectContext.ObjectMaterialized +=
HandleObjectMaterialized;
方法:
private void HandleObjectMaterialized(object sender, ObjectMaterializedEventArgs e)
{ }
现在的问题是,方法体中应该放什么?也许最简单的解决方案是定义一个接口(interface)
interface IChangeTracker
{
bool Materialized { get; set; }
bool OutsideDbNeedsUpdate { get; }
}
并让你想要跟踪的类实现这个接口(interface)。
然后,在 HandleObjectMaterialized
中您可以执行以下操作:
var entity = e.Entity as IChangeTracker;
if (entity != null)
{
entity.Materialized = true;
}
在此之后,您就知道何时可以在内部设置 OutsideDbNeedsUpdate
。
原文
一般来说,不建议使用带有副作用的属性(嗯,更准确地说,比改变所代表的状态有更多的副作用)。也许这条规则有异常(exception),但大多数时候,属性之间存在依赖关系并不是一个好主意。
我必须猜测一下你能做的最好的事情,因为我不知道你真正的代码是关于什么的,但也许可以将逻辑放在 setter/getter 中。只是一个例子:
public State State
{
get { return this.EndDate.HasValue ? MyState.Completed : this._state; }
set { this._state = value; }
}
这不会消除相互依赖性,但会将生效时间推迟到访问属性的时间。在您的情况下,这可能不会早于 SaveChanges()
。
另一种策略是创建一个同时设置两个属性的方法。方法预计会有副作用,尤其是当它们的名称明确表明它时。您可以使用类似 SetMasterAndDependent (string master)
的方法。
现在的方法在数据绑定(bind)场景中并不方便。在这种情况下,您最好让 View 模型设置这两个属性或调用上面的方法。
关于c# - 当另一个属性更改时更新实体属性(实体初始化后),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/14363619/