Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/268.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 检测复杂对象的更改_C#_.net_Entity Framework - Fatal编程技术网

C# 检测复杂对象的更改

C# 检测复杂对象的更改,c#,.net,entity-framework,C#,.net,Entity Framework,我有一个BO,其中包含一些依赖的BO(通过导航属性),它们表示数据库中的几个链接表。例如,个人主表和地址、教育表,通过个人地址、个人教育表1对多链接 我们需要跟踪特定人员在人员、地址、教育表上发生的变化。这三个表中的任何更新都应将Person.LastRecordUpdate日期更新为当前日期。我认为跟踪Person表本身没有任何问题。但是,我们需要跟踪其他两个表(Address、Education)中的更改,这两个表具有AddressId、EducationId PKs和no PersonId

我有一个BO,其中包含一些依赖的BO(通过导航属性),它们表示数据库中的几个链接表。例如,个人主表和地址、教育表,通过个人地址、个人教育表1对多链接


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

我从包含
公共虚拟日期时间的模型库中派生所有业务对象?LastModified属性。它还实现了接口

public interface IHasLastModified
{
    DateTime? LastModified { get; set; }
}
然后在my
DbContext
中重写
SaveChanges()
,以查找正在添加或修改的任何实现
IHasLastModified
的内容,并设置修改后的时间戳

另一方面,EF在调试器中显示
DbEntityValidationException
详细信息方面有些古怪。因此,在这段代码中,我也处理了这个问题 通过生成可在调试器中直接查看的
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;
    }
}
public override int SaveChanges()
{
尝试
{
DateTime now=DateTime.UtcNow;
foreach(中的ObjectStateEntry条目(作为IOObjectContextAdapter)。ObjectContext.ObjectStateManager.GetObjectStateEntries(EntityState.Added | EntityState.Modified))
{
//logger.Info(“在“+entry.Entity.GetType().FullName”上设置LastModified);
如果(!entry.IsRelationship)
{
IHasLastModified lastModified=条目。实体为IHasLastModified;
如果(lastModified!=null)
lastModified.lastModified=现在;
}
}
返回base.SaveChanges();
} 
捕获(DbEntityValidationException valEx)
{
List errorList=新列表();
foreach(valEx.EntityValidationErrors中的var错误)
{
foreach(var条目出错。ValidationErrors)
{
errorList.Add(entry.PropertyName+:“+entry.ErrorMessage);
}
logger.Error(string.Join(“;”,errorList));
}
投掷;
}
}
保存在地址中,教育发生在另一个dbcontext实体中,即保存人

跨多个DbContext实例合并更改是非常非常棘手的。EF并不是为所有场景提供完全支持

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

如果您确实想尝试和管理在两个上下文实例中发生的更改,请查看。注意结论意见

到目前为止,EF不支持完全对象图合并,并将其留给您自己管理


你为什么要用摇摆台来做一对多的桌子?你的意思是多对多关系(许多用户可以拥有相同的教育或地址)?我通常会覆盖
SaveChanges
,但使用
LastModified
的界面是一个很好的主意。我将在我的下一个项目中实施它!Eric,您的解决方案在这种情况下有何帮助:假设我有以下数据库内容:Person.LastRecordUpdate;我在地址表中还有一个地址记录,它通过Person_地址表与Person表链接(正确,多对多)。我修改了地址记录中的邮政编码,那么我应该如何跟踪它,以便能够自动更新Person.LastRecordUpdate值?@TakhirMamirov:保存的每个实体都会自动应用时间戳。将我的
LastModified
更改为您的
LastRecordUpdate
。不管是父母还是孩子,让我把任务复杂化。MemberInfo表与person 1对1链接。有一个字段MemberInfo.LastModified。还有那两个卫星表-教育,地址,和人联系。问题:在DB中修改教育或地址实体时,需要MemberInfo.LastModified更新。请共享哪些类应继承该BaseModel,哪些不应继承,以及哪些类应具有LastModified属性。注:并非所有BO都需要该属性。只有MemberInfo。简单。。。每个需要自动设置时间戳的对象都继承自ModelBase。