保留对Entity Framework对象的更改记录

时间:2013-05-28 11:05:33

标签: c# entity-framework

我正在编写一个从各种来源接收人员信息的软件,所有这些数据都存储在数据库中。棘手的部分是将这些信息合并到主记录中。这种组合被实现为不同类型步骤的流水线,其根据从源接收的信息更新主记录。所有步骤都实现了一个具有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?
}

0 个答案:

没有答案