使用 Automapper 的异常:无法跟踪实体类型的实例,因为已在跟踪具有该键的另一个实例

Sae*_*eid 3 automapper entity-framework-core asp.net-core

我将 ASP.NET Core 与 EFCore 2.0.3 和 Automapper 6.2.2 一起使用

这是我的模型:

    public class StudentClass
    {
        public int Id { get; set; }
        public int ClassId { get; set; }
        public Class Class { get; set; }
        public int ProfId { get; set; }
        public Professor Prof { get; set; }
        public string Description { get; set; }
        public DateTimeOffset LastUpdateTime { get; set; }
        public DateTimeOffset CreateTime { get; set; }
    }
Run Code Online (Sandbox Code Playgroud)

和我的实体

    public class StudentClassEntity
    {
        public int Id { get; set; }

        public int ClassId { get; set; }
        [ForeignKey("ClassId")]
        public virtual Class Class { get; set; }
        public int ProfId { get; set; }
        [ForeignKey("ProfId")]
        public Professor Prof { get; set; }
        public string Description { get; set; }
        public DateTimeOffset LastUpdateTime { get; set; }
        public DateTimeOffset CreateTime { get; set; }
        public virtual List<Task> Tasks { get; set; }
    }
Run Code Online (Sandbox Code Playgroud)

我尝试更新StudentClass所以这是我的示例方法:

        public void Update()
        {

            var studentclass = new StudentClass();
            studentclass.Id = 7;
            studentclass.CreateTime = System.DateTimeOffset.MinValue;
            studentclass.Description = $"new desc - {System.DateTime.Now.Millisecond}";
            studentclass.ProfId = 5;
            studentclass.ClassId = 7;


            var entity = _context.StudentClasses.FirstOrDefault(x => x.Id == studentclass.Id);

            if (entity != null)
            {
                entity = _mapper.Map<StudentClassEntity>(studentclass);
                _context.StudentClasses.Update(entity);
                _context.SaveChanges();
            }
        }
Run Code Online (Sandbox Code Playgroud)

还有我的 Automapper 地图:

 CreateMap<StudentClass, StudentClassEntity>()
 .ForMember(m => m.Description, o => o.MapFrom(x => x.Description))
 .ForMember(m => m.LastUpdateTime, o => o.MapFrom(f => DateTimeOffset.Now))
 .ForAllOtherMembers(m => m.UseDestinationValue());
Run Code Online (Sandbox Code Playgroud)

所以我得到了例外:

The instance of entity type cannot be tracked because another instance with the key value "Id:7" is already being tracked.
Run Code Online (Sandbox Code Playgroud)

但是,如果我不使用 Automapper,而是手动映射:

if (entity != null)
{
     //entity = _mapper.Map<StudentClassEntity>(studentclass);
    entity.Description = studentclass.Description;
    entity.LastUpdateTime = DateTimeOffset.Now;

    _context.StudentClasses.Update(entity);
    _context.SaveChanges();
}
Run Code Online (Sandbox Code Playgroud)

它将无一例外地更新数据库。问题出在哪儿?我错过了什么吗?如何在 Automapper 中创建 Map 以毫无例外地更新实体?

Sae*_*eid 6

我发现如果我使用

entity = _mapper.Map<StudentClassEntity>(studentclass);
Run Code Online (Sandbox Code Playgroud)

Automapper 将为实体创建新对象,显然它在上下文中不是相同的引用。但如果我用

_mapper.Map(studentclass, entity);
Run Code Online (Sandbox Code Playgroud)

Automapper 不创建新实例,实体与上下文中的引用相同。