我在使用实体框架更新被跟踪的实体时遇到问题.我正在使用DotNet 6. 假设我有一个SnapshotEntity和一个UpdateSnapshotDto. 更新快照Dto它被用作‘输入’,它从前端获取字段.我使用AutoMapper将UpdateSnapshotDto转换为SnapshotEntity. 我try 过的最简单的方法(失败了)是这样的:

        var oldSnapshot = await snapshotRepository.GetSingleOrDefaultAsync(e => e.Id == request.snapshot.Id);
        var newSnapshot = mapper.Map<SnapshotEntity>(request.snapshot);

        oldSnapshot = newSnapshot;
        await snapshotRepository.SaveChangesAsync();

但当然不起作用,因为当我指定oldSnapshot=newSnapshot时,它可能会丢失跟踪.

所以我想我可以从输入中更新,就像这样:

        var newSnapshot = mapper.Map<SnapshotEntity>(request.snapshot);
        snapshotRepository.Update(newSnapshot);

但是这种方法对我来说不起作用,因为如果我像这样进行暴力更新,我会丢失一些保存在原始快照中的东西(例如,在DB中,旧快照有一个CreatedDate和列,这些列不会在UpdateSnapshotDto中传递).

所以我想读取文件,赋值,然后像这样更新:

        var oldSnapshot = await snapshotRepository.GetSingleOrDefaultAsync(e => e.Id == request.snapshot.Id);
        var newSnapshot = mapper.Map<SnapshotEntity>(request.snapshot);

        newSnapshot.CreatedDate = oldSnapshot.CreatedDate;
        newSnapshot.CreatedBy = oldSnapshot.CreatedBy;
        snapshotRepository.Update(newSnapshot);

但这两种方法都不起作用,因为oldSnapshot是被跟踪的,当我try 执行更新方法时,它告诉我它已经被跟踪了.

我找到了两个解决方案,但我不想使用它们:

  • 第一个解决方案是我逐个字段为oldSnapshot赋值,例如oldSnapshot.Name=newSnaphot.Name等,但实际上我会避免使用这种方法,因为如果快照会增加属性,这个逻辑将不再起作用,需要修复;
  • 第二个解决方案是,我使用我所描述的第三种try ,但是使用AsNoTrack()读取实体,并且我希望避免在项目中引入AsNoTrack()逻辑.

有什么主意吗?另一种解决方案可能是使用反射在旧的跟踪实体上分配所有新的实体,但我不知道如何做到这一点,对于简单的更新来说,它可能太高了.

推荐答案

我使用AutoMapper将UpdateSnapshotDto转换为SnapshotEntity.

AutoMapper具有从数据映射到现有实例的能力,因此您可以只使用它而不是创建新的实例:

mapper.Map(request.snapshot, oldSnapshot);

// ...

await snapshotRepository.SaveChangesAsync();

另请参见AutoMapper.Collection.

Csharp相关问答推荐

使用客户端密钥为Fabric Rest API生成令牌

为什么C#Bigbit不总是相同的比特长度?

图形API基于appid列表检索多个应用程序

Quartz调度程序不调用作业(job)类

如何使用EF Core和.NET 8来upsert到具有多对多关系的表?

为基本审计设置Audit.EntityFramework.Core

BlockingCollection T引发意外InvalidOperationException

为什么AggregateException的Catch块不足以处理取消?

有没有类似于扩展元素的合并元组的语法?

是否有必要在ASP.NET Core中注册可传递依赖项?

Google OAuth令牌交换在.Net中不起作用

为什么我的用户界面对象移动到略低于实际目标?

如何使用类似于[SELECT*FROM&Q;&Q;WHERE&Q;]SQL查询的System.Data.Entity创建查询?

序列化过程中的死循环

Linq SELECT的多条指令

如何将 colored颜色 转换为KnownColor名称?

WPF:如何从DatagridHeader的内容模板绑定到词典项

读取测试项目中的应用程序设置

测试单个对象是否与Func<;T,bool>;匹配

ASP.NET重新加载Kestrel SSL证书