gpt4 book ai didi

c# - ChangeLog OriginalValue 与 EF Core 更新实体上的 CurrentValue 相同

转载 作者:太空宇宙 更新时间:2023-11-03 22:33:25 24 4
gpt4 key购买 nike

我在更新 EF Core 中的实体然后在表中记录这些更改时遇到了问题。使用的技术是:

  • .NET 核心 2.2.0
  • EF 核心 2.2.3

所以,我想从数据库中获取一个实体,在前端对其进行编辑,然后在后端对其进行更新,并将这些更改保存到数据库中。最重要的是,我有一个名为 ChangeLogs 的表,其中最重要的字段是 From(映射自 OldValues)和 To(映射自 CurrentValues ).嗯,这两个字段是相同的(意味着它们具有完全相同的值,新值)并且情况是这样的:

  1. 我这样从数据库中获取实体

    _context.Anomalies
    .Include(a => a.Asset)
    .FirstOrDefaultAsync(a => a.Id == anomalyId)

  2. 在前端编辑实体,然后发起PUT请求更新实体;

  3. 更新实体:

    为了使 Update() 工作,首先我必须调用它:_context.DetachAllEntities(); 否则我会收到一条错误消息,指出已跟踪具有相同 ID 的实体。然后调用 Update()SaveChanges():

    _context.Anomalies.Update(异常);
    _context.SaveChanges();

    异常 对象是来自请求的对象。

  4. 对于 ChangeLog 部分,我在 this example 之后重写了 SaveChanges() 方法,旧/原始值和新/当前值设置如下:
    auditEntry.OldValues[propertyName] = property.OriginalValue;
    auditEntry.NewValues[propertyName] = property.CurrentValue;

    基本上这会遍历 ChangeTracker 中的所有条目,创建一个 AuditEntry 并在 base.SaveChanges() 之后返回并设置该 AuditEntry 的 EntityId,因为您在保存更改之前没有它(这是为了防止您添加新实体,对于更新,保存更改后没有任何反应)。

Update() 方法正在运行,更改反射(reflect)在数据库中。但唯一的问题是 ChangeLogs,来自 ChangeTracker.Entries() 的条目不知道 OldValues


我承认我不完全了解 EF 使用的跟踪系统,但我想它应该可以帮助我更新实体而不是产生问题。因为我知道调用 _context.DetachAllEntities(); 是不正确的。我尝试使用 AsNoTracking() 并删除 DetachAllEntities() 但结果似乎是一样的。我想过使用 dbEntity,将每个字段从请求实体复制到数据库实体,然后 Update(dbEntity) 但这似乎需要做很多工作,基本上只是为了获得一点好处。我的 Anomaly 实体有很多导航属性,很难为其创建复制方法并进行维护。

DetachAllEntities() 定义如下:

public static void DetachAllEntities(this DbContext context)
{
var entries = context.ChangeTracker.Entries().ToList();
foreach (var entry in entries)
{
entry.State = EntityState.Detached;
}
}

DbContext 设置为 Scoped 生命周期,管理器也是如此。

我尝试使用来自 this tutorial 的审核方法也一样,但结果是一样的。

我担心整个更新过程没有正确完成,因此出现了这个问题..

UPDATE I have created a sample project to exemplify this problem. You can check the source code on bitbucket. The README hase some more info on this

我序列化了从上下文中检索到的对象。

在左侧有跟踪 <====> 在右侧没有跟踪 With Tracking on the LEFT <====> With NO tracking on the RIGHT

欢迎任何建议、意见、新想法、评论。谢谢!

最佳答案

enter image description here

我想你的问题就在这里。因为这两个对象存在于不同的上下文中,所以从根本上说是不同的对象。如果更改代码以便从数据库中检索实体,更新其值,然后使用该对象传递给 SaveChangesAndAudit() 方法。你会得到你期望的结果。我已经调整了所附屏幕截图中的代码。您还会遇到大多数开发人员发现的一个基本问题,那就是映射对象——像 Automapper 这样的工具可以让您的生活更轻松——所以如果您的实体很大,那么值得一看以提供帮助; -)

https://github.com/AutoMapper/AutoMapper

关于c# - ChangeLog OriginalValue 与 EF Core 更新实体上的 CurrentValue 相同,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/56233528/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com