2016-12-13 9 views
0

Я использую EF Core и Automapper для обновления моих объектов. У меня есть объект под названием «Aluno», который имеет отношение к «Endereco». Вот код:Использование automapper для обновления объектов с отношениями

public class Aluno : ApplicationUser{ 

    ... 
    public Endereco Endereco { get; set; } 
    ... 
} 

public class AlunoViewModel : UserViewModel 
{ 
    public int Id { get; set; } 

    public EnderecoViewModel Endereco { get; set; } 
} 

public class Endereco{ 

    [Key] 
    [DatabaseGenerated(DatabaseGeneratedOption.Identity)] 
    public int Id { get;set; } 

    ... 
} 

public class EnderecoViewModel { 

    public int Id { get;set; } 
    ... 
} 

Конфигурация automapper:

config.CreateMap<Aluno, AlunoViewModel>().ReverseMap(); 
config.CreateMap<Endereco, EnderecoViewModel>().ReverseMap(); 

AlunosController:

[HttpPut] 
    public JsonResult Put([FromBody]AlunoViewModel vm) 
    { 
     if (ModelState.IsValid) 
     { 
      var aluno = _context.Alunos 
       .Single(o => o.Id == vm.Id); 

      Mapper.Map(vm, aluno); 

      _context.SaveChanges(); 

      Response.StatusCode = (int)System.Net.HttpStatusCode.OK; 
      return Json(true); 
     } 

     Response.StatusCode = (int)System.Net.HttpStatusCode.BadRequest; 
     return Json(false); 
    } 

Когда я пытаюсь обновить "Aluno" лицо, я получаю исключение на context.SaveChanges():

Невозможно вставить явные значение для столбца идентификации в таблице 'Enderecos' , когда для параметра IDENTITY_INSERT установлено значение OFF.

Но я не пытаюсь вставить новую «Endereco», просто обновить объект «Aluno», и, возможно, обновить «Endereco», которая правильно загружена внутри вар aluno.

Я что-то не так?

+1

Я думаю, у вас есть проблема отображения. Перед сохранением убедитесь, что ваши сопоставления верны. Для вашего сопоставления Aluno необходимо, чтобы функция «ForMember» определяла отображение для своих объектов свойств. Можете ли вы попытаться добавить ForMember (i => i.Endereco, i => i.MapFrom (s => s.Endereco)). – kizilsu

+0

Вы правы! Не могли бы вы разместить его в качестве ответа, чтобы я мог отметить его? Спасибо! – Munir

+0

@Munir: Пожалуйста, не злоупотребляйте AutoMapper, чтобы привязываться к объектам, это вызовет у вас большие проблемы, особенно при сопоставлении коллекций. AutoMapper является и никогда не предназначался для двухсторонних сопоставлений. Пожалуйста, прочитайте сообщение автора AutoMapper здесь https://lostechies.com/jimmybogard/2009/09/18/the-case-for-two-way-mapping-in-automapper/ в вариантах использования, для которых был предназначен AutoMapper и работает хорошо. Попытка злоупотребления им для двухстороннего связывания результатов: а) модели ваших доменов, нарушающих encapuslation, для поддержки этого; б) ваша модель персистентности/ORM Mapper, имеющая проблемы со связями. – Tseng

ответ

1

Попробуйте следующий синтаксис:

Mapper 
    .CreateMap<Aluno, AlunoViewModel>() 
    .ForMember(
     dest => dest.Endereco, 
     opt => opt.MapFrom(src => src.EnderecoViewModel) 
    ); 
+0

Извините, вам необходимо использовать нижний предел. Хотя это может решить ближайшую проблему, вы просто поощряете OP и других использовать AutoMapper неправильно. AutoMapper не предназначен для использования в двухсторонних привязках к моделям доменов или модели настойчивости! https://lostechies.com/jimmybogard/2009/09/18/the-case-for-two-way-mapping-in-automapper/ – Tseng

+0

Я никому не рекомендую использовать какой-либо конкретный способ сделать что-либо, просто показал, как AutoMapper следует использовать, если они его используют, нет необходимости понижать значение @Tseng – Yaser

+0

@Tseng, хотя ваша точка почти права, я не думаю, что это справедливо, чтобы опросить ответ. Это решает проблему, и downvoting не поможет другим людям. Что действительно помогло бы, чтобы опубликовать ответ с решением, которое вы считаете наиболее подходящим. – Munir