其他分享
首页 > 其他分享> > 核心MVC中的AutoMapper 5.2.0 VIewModel建模问题

核心MVC中的AutoMapper 5.2.0 VIewModel建模问题

作者:互联网

楷模:

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

    public string Name {get;set;}

    public Address Address {get;set;}

    public int AddressId  {get;set;}
}

public class Address{
   public int Id

   public string Address1 {get;set;}

   public string PostCode {get;set;}
}

查看模型:

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

        public string Name {get;set;}

        public Address Address {get;set;}

        public int AddressId  {get;set;}
    }

    public class AddressViewModel{
       public int Id

       public string Address1 {get;set;}

       public string PostCode {get;set;}
    }

对应:

 Mapper.Initialize(config =>
    {
        config.CreateMap<ClientViewModel, Client>().ReverseMap();
        config.CreateMap<AddressViewModel, Address>().ReverseMap();
    });

控制器更新操作:

[HttpPost]
public async Task<IActionResult> Update(cLIENTViewModel viewModel)
{
    if (!ModelState.IsValid)
    {
        return View("Client",viewModel);
    }

    var client= _clientRepository.GetClient(viewModel.Id);
    if (client == null) 
        return NotFound();

    client= Mapper.Map<ClientViewModel, Client>(viewModel);

    _clientRepository.Update(client);
    var result = await _clientRepository.SaveChangesAsync();

    if (result.Success)
    {
        return RedirectToAction("Index");
    }

    ModelState.AddModelError("", result.Message);

    return View("Client",viewModel);
}

问题是,当调用_clientRepository.Update(client)时,我收到一条错误消息,指出:

The instance of entity type ‘Client’ cannot be tracked because another instance of this type with the same key is already being tracked. When adding new entities, for most key types a unique temporary key value will be created if no key is set (i.e. if the key property is assigned the default value for its type). If you are explicitly setting key values for new entities, ensure they do not collide with existing entities or temporary values generated for other new entities. When attaching existing entities, ensure that only one entity instance with a given key value is attached to the context.

当我调试代码时,可以看到将viewModel映射到模型时,客户端模型中的AddressID设置为0.我猜这是引起问题的原因.

如何将viewModel映射回将更新地址详细信息的模型,例如Address1和Postcode而不是Id.

我还尝试在使用.ForMember(x => x.AddressId,opt => opt.Ignore())的映射中忽略地址ID的映射

但是仍然将AddressId设置为0.

我想念什么?

解决方法:

当您执行Mapper.Map< ClientViewModel,Client>(viewModel)时,AutoMapper将创建一个新的Client对象,其ID与现有的Client对象相同.

然后,您指示EntityFramework更新此对象图. Entity Framework不会跟踪新的Client对象,因此会将对象附加到其内部魔术缓存/跟踪工具.由于ID冲突,此操作失败.因此,错误“无法跟踪实体类型’Client’的实例,因为已经跟踪了具有相同密钥的该类型的另一个实例”.

这也是0 AddressId的来源. Address对象也是由AutoMapper创建的全新对象,并且该属性具有值default(int),因为AutoMapper在创建后再也不会为其分配其他值.

标签:asp-net-core,asp-net-core-mvc,automapper-5,c
来源: https://codeday.me/bug/20191112/2023726.html