1

我正在编写一个软件,它从各种来源接收人员信息,所有这些数据都存储到数据库中。棘手的部分是当这些信息被合并到主记录时。这种组合被实现为不同类型步骤的管道,这些步骤根据从源接收的信息更新主记录。所有步骤都实现了一个IPersonUpdatingStep具有Update(Person person)方法的通用接口。

我想记录哪些更新的字段,特别是哪个步骤负责更改。不同的步骤可能会更新同一个字段,我只对主记录通过整个管道后出现的最后一次更改感兴趣。

我的第一个直觉是在对象进入一个步骤时对其进行深拷贝,在它返回后进行另一个深拷贝,并根据这些副本进行差异。然而,深度复制使用 Entity Framework 的 Database First 工具生成的类的对象似乎相当困难。如果浅拷贝就足够了,那将非常容易,但我需要知道存储在集合中的任何相关实体是否已更改。

一个建议的深度复制简单解决方案是序列化和反序列化对象,但由于模型是基于数据库自动生成的,我无法添加这些 Serializable 属性。

问题更加困难,因为该对象具有相关实体和相关实体的集合,因此我需要知道某些步骤是否更改了这些相关集合实体的某些属性。

我不想更改管道步骤,以便每个步骤都包含如下代码:

if (targetPerson.FirstName != sourcePerson.FirstName)
{
    targetPerson.FirstName = sourcePerson.FirstName;
    changes.Add("FirstName", "Name of the step responsible for the change");
}

但是还有另一种可读且可靠的选择吗?我知道在将对象保存到数据库时如何使用 Entity Framework 编写审计跟踪,但在那个阶段我只能记录哪些属性已更改,而我更感兴趣的是哪个管道步骤负责更改场地。

我觉得我没有做任何开创性的事情,以至于其他人不会遇到同样的问题。

更新: haim770 关于 ChangeTracker API 的建议很好。我设法获取有关更改的基本属性的信息,但是如何获取有关更改的关系的信息?例如,我的Person对象与对象具有一对多的关系Address。我想获得的信息不仅是关于哪个Address对象被更新,更具体地说,是那个Address对象的哪个属性被改变了。

DbEntityEntry entry = _source.Context.Entry(person);
foreach (var property in entry.Entity.GetType().GetProperties())
{
    DbMemberEntry propertyEntry = entry.Member(property.Name);
    if (propertyEntry is DbPropertyEntry)
    {
        var foo = propertyEntry as DbPropertyEntry;
        if (foo.IsModified)
        {
            changes.Add(step.GetType().Name + ": " + property.Name);                            
        }
    }

    // How to handle relationships?
}
4

0 回答 0