检测复杂对象的更改

时间:2015-10-07 16:37:04

标签: c# .net entity-framework

我有一个带有一些依赖BO的BO(通过导航属性),它代表数据库中的几个链接表。例如,Person主表和Address,Education表,通过Person_Address,Person_Education表,1对多链接。

我们需要跟踪特定人员在“人员”,“地址”,“教育”表格中发生的更改。这三个表中的任何更新都应将Person.LastRecordUpdate日期更新为当前日期。我没有看到跟踪Person表本身的任何问题。但是,我们需要跟踪其他两个表(Address,Education)中的更改,这两个表具有AddressId,EducationId PK和没有PersonId(因为它们通过中间表与主表链接)。并且保存在Address中,教育发生在另一个dbcontext实体中,即人员的节省。我该如何解决这个问题?

1 个答案:

答案 0 :(得分:1)

我从包含public virtual DateTime? LastModified属性的ModelBase派生所有业务对象。它还实现了接口

public interface IHasLastModified
{
    DateTime? LastModified { get; set; }
}

然后我覆盖SaveChanges()中的DbContext以查找实现IHasLastModified的任何添加或修改内容,并设置修改后的时间戳。

另外,关于在调试器中显示DbEntityValidationException详细信息,EF很奇怪。出于这个原因,在这段代码中我也处理了这个问题 通过构建在调试器中直接查看的errorList的异常,并记录详细信息。在我的代码中,logger是NLog记录器。您可以 使用任何其他记录器,或删除该行。

public override int SaveChanges()
{
    try
    {
        DateTime now = DateTime.UtcNow;
        foreach (ObjectStateEntry entry in (this as IObjectContextAdapter).ObjectContext.ObjectStateManager.GetObjectStateEntries(EntityState.Added | EntityState.Modified))
        {
            //logger.Info("Setting LastModified on " + entry.Entity.GetType().FullName);
            if (!entry.IsRelationship)
            {
                IHasLastModified lastModified = entry.Entity as IHasLastModified;
                if (lastModified != null)
                    lastModified.LastModified = now;
            }
        }

        return base.SaveChanges();
    } 
    catch (DbEntityValidationException valEx)
    {
        List<string> errorList = new List<string>();

        foreach (var error in valEx.EntityValidationErrors)
        {
            foreach (var entry in error.ValidationErrors)
            {
                errorList.Add(entry.PropertyName + ": " + entry.ErrorMessage);
            }

            logger.Error(string.Join(";", errorList));
        }
        throw;
    }
}
  

并且保存在地址中,教育发生在另一个dbcontext实体中,即人员保存。

跨多个DbContext实例合并更改非常非常棘手。 EF不会为所有方案提供全面支持。

我强烈建议避免这种情况。传递DbContext的单个实例,而不是尝试合并来自两个DbContext图像的更改。

如果您真的想尝试管理两个上下文实例中发生的更改,请查看this writeup。请注意结束语

  

截至今天,EF不支持完整对象图合并,并且可以让您自行管理。