跟踪自定义对象中每个属性的属性更改

本文关键字:属性 自定义 对象 跟踪 | 更新日期: 2023-09-27 18:01:00

我四处寻找,但一直找不到能充分解决我的问题的解决方案。

我有一个正在用各种模型类构建的应用程序。目前,我正在数据库层工作。我的最终目标是:

public void SomeMethod(ModelObject param)
{
    IEnumerable<IModelObject> results = DatabaseLayer.Get(param);
}

基本上,我想向数据库层传递一个模型对象,并将属性集用作稍后在查询的Where子句中构造的参数。

我的问题很简单:不可为null的类型。然而,我不希望将所有模型属性类型更改为

public int? intProperty { get; set; }
public DateTime? dateTimeProperty { get; set; }

我想知道是否有一种简单的方法来区分默认值和设置值,以查看更改了什么。可以通过属性的方式,也可以通过构建列表的方式跟踪属性集调用的特定于模型的逻辑。我非常反对将它们设置为可为null的类型。

数据库Get方法的伪代码类似于:

public IEnumerable<IModelObject> Get(ModelObject param)
{
    //Iterate through ModelObject parameters to find non-default values
    //Write these into a where clause
    //Query and return IEnumerable of serialized results from database
}

如果需要更多信息,请告诉我。谢谢

跟踪自定义对象中每个属性的属性更改

无法区分值类型的默认值和恰好是默认值的集合值。

您要么必须使用可为null的类型,要么必须做一些笨拙的事情,比如为每个属性维护一个布尔值,当属性值更改时设置该布尔值。

我会说使用可以为null的类型;这就是他们来这里的目的。

免责声明:我是我要向你推荐的库的作者


由于其他一些要求,我必须开发一个库来跟踪任何对象的更改,所以我实现了TrackerDog,这是一个托管在GitHub上的开源项目。

如果你想跟踪变化,只需以下步骤即可:

var config = ObjectChangeTracking.CreateConfiguration();
config.TrackThisType<YourModelClass>();
var trackableObjectFactory = config.CreateTrackableObjectFactory();
var model = new YourModelClass();
var trackableModel = config.CreateFrom(model);
// Now perform changes to the whole trackable model:
trackableModel.Text = "hello world";
// Then you can get what properties have changed whenever you want
// using an extension method to get the change tracker associated to
// your model
var changeTracker = trackableModel.GetChangeTracker();
var changedProperties = changeTracker.ChangedProperties;
// or even unchanged ones:
var unhangedProperties = changeTracker.UnchangedProperties;

我相信,您应该能够用TrackerDog满足您的更改跟踪需求,如果您觉得需要一些新功能或增强现有功能,请随时填写问题,我们可以在那里讨论!

您也可以遵循本教程,该教程将逐步向您解释所有可用的功能。

关于区分值类型的默认值

如果某个属性的值与构造函数或初始值设定项在构造时设置的值不同,TrackerDog将能够告诉您该属性是否已更改。例如,如果一个属性是int,并且它设置为0,则上一个值和新值将相等,因此,它根本没有更改。顺便说一句,正如我之前所说,你可以在GitHub存储库中填写一个问题,我们可以讨论如何实现这个需求。

从我的角度来看,当属性类型为值类型时,只要设置了属性,就可以很容易地告诉TrackerDog,您希望考虑到该属性已经更改。实现这个功能并不困难。