Uso ASP.NET Core con EFCore 2.0.3 e Automapper 6.2.2
Ecco il mio modello:
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; }
}
E la mia entità
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; }
}
E ho provato ad aggiornare StudentClass
Quindi ecco il mio metodo di esempio:
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();
}
}
E la mia mappa di 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());
Quindi ho ottenuto l'eccezione:
The instance of entity type cannot be tracked because another instance with the key value "Id:7" is already being tracked.
Ma se invece di usare Automapper, mi limito a mappare manualmente:
if (entity != null)
{
//entity = _mapper.Map<StudentClassEntity>(studentclass);
entity.Description = studentclass.Description;
entity.LastUpdateTime = DateTimeOffset.Now;
_context.StudentClasses.Update(entity);
_context.SaveChanges();
}
Sarebbe aggiornato DB senza eccezioni. Dov'è il problema? Ho perso qualcosa? Come creare Map in Automapper per aggiornare l'entità senza eccezioni?
Ho scoperto che se uso il
entity = _mapper.Map<StudentClassEntity>(studentclass);
Automapper creerà il nuovo oggetto per entità e ovviamente non è lo stesso riferimento nel contesto. Ma se l'avessi usato
_mapper.Map(studentclass, entity);
Automapper non crea la nuova istanza e l'entità è lo stesso riferimento nel contesto.