У меня есть трехслойное приложение. Слоями являются DAL, BL и UI. Я использую automapper для преобразования моих объектов, взятых из контекста базы данных, в уровни уровня выше. Насколько я вижу, сопоставленные объекты больше не отслеживаются EF.Как обновить объект в базе данных с помощью DTO с помощью Entity Framework
В любом случае проблема, с которой я сталкиваюсь, возникает в момент обновления сущностей, существующих в БД, а точнее - для объектов ETO обновления объектов ETO. DTO с верхнего уровня отображается обратно в объект для завершения операции обновления. Однако сопоставлено с объектом DTO, и все его навигационные свойства и коллекции не существуют в контексте, потому что они не отслеживаются.
EF принимает этот объект и его сущности как новую информацию, не принимая во внимание тот факт, что этот объект и некоторые объекты, включенные в него, уже могут существовать в контексте.
Вот пример.
У меня есть две модели, Student
и Standard
.
public class Student
{
[Key]
public Guid StudentID { get; set; }
public string StudentName { get; set; }
public DateTime DateOfBirth { get; set; }
public decimal Height { get; set; }
public float Weight { get; set; }
public Standard Standard { get; set; }
}
public class Standard
{
[Key]
public Guid StandardId { get; set; }
public string StandardName { get; set; }
public ICollection<Student> Students { get; set; }
}
Мой контекст:
public class SchoolContext : DbContext
{
public DbSet<Student> Students { get; set; }
public DbSet<Standard> Standards { get; set;}
}
У меня также есть StudentMap
и StandardMap
, которые выглядят так же, как модели, упомянутых выше.
Automapper Профиль:
public class AutomapperProfile : Profile
{
protected override void Configure()
{
Mapper.CreateMap<Student, StudentMap>();
Mapper.CreateMap<StudentMap, Student>();
Mapper.CreateMap<Standard, StandardMap>();
Mapper.CreateMap<StandardMap, Standard>();
}
}
А вот код я бегу:
Mapper.AddProfile(new AutomapperProfile());
var student1 = new Student
{
DateOfBirth = DateTime.Now,
Height = 195,
StudentID = Guid.NewGuid(),
StudentName = "Bob",
Weight = 144
};
var student2 = new Student
{
DateOfBirth = DateTime.UtcNow,
Height = 170,
StudentID = Guid.NewGuid(),
StudentName = "John",
Weight = 95,
};
var standard = new Standard
{
StandardId = Guid.NewGuid(),
StandardName = "New Standard",
Students = new List<Student> { student1 }
};
using (var schoolContext = new SchoolContext())
{
schoolContext.Standards.Add(standard);
schoolContext.Students.Add(student2);
schoolContext.SaveChanges();
var standardInContext = schoolContext.Standards.First();
var studentInContext = schoolContext.Students.First(student => student.StudentID == student2.StudentID);
var mappedStandad = Mapper.Map<Standard, StandardMap>(standardInContext);
var mappedStudent = Mapper.Map<Student, StudentMap>(studentInContext);
mappedStandad.Students.Add(mappedStudent);
var standardEf = Mapper.Map<StandardMap, Standard>(mappedStandad);
//On attach attempt exception will be thrown
//because standard with the same Id already exist in context
schoolContext.Set<Standard>().Attach(standardEf);
schoolContext.Entry(standardEf).State = EntityState.Modified;
// with this solution two additional student will be added to the context,
// exception will be thrown on SaveChanges, because students with
// same ID already exist
// var standardEf = Mapper.Map(mappedStandad, standardInContext);
// schoolContext.Set<Standard>().Attach(standardEf);
// schoolContext.Entry(standardEf).State = EntityState.Modified;
schoolContext.SaveChanges();
}
Я буду благодарен за любую помощь! Я исследовал все, что мог, но напрасно.
хорошо, в вашем случае проблема возникает при когда вы обновляете объект в контексте с помощью метода Mapper.Map
Спасибо, похоже, решение моей проблемы. Но она становится обычной, когда мой объект содержит много ссылок на другие объекты –