Warning: file_get_contents(/data/phpspider/zhask/data//catemap/0/asp.net-core/3.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# AutoMapper 5.2.0视图模型到核心MVC中的模型问题_C#_Asp.net Core_Asp.net Core Mvc_Automapper 5 - Fatal编程技术网

C# AutoMapper 5.2.0视图模型到核心MVC中的模型问题

C# AutoMapper 5.2.0视图模型到核心MVC中的模型问题,c#,asp.net-core,asp.net-core-mvc,automapper-5,C#,Asp.net Core,Asp.net Core Mvc,Automapper 5,型号: 查看模型: 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 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.CreateMap().ReverseMap();
config.CreateMap().ReverseMap();
});
控制器更新操作:

 Mapper.Initialize(config =>
    {
        config.CreateMap<ClientViewModel, Client>().ReverseMap();
        config.CreateMap<AddressViewModel, Address>().ReverseMap();
    });
[HttpPost]
公共异步任务更新(cLIENTViewModel viewModel)
{
如果(!ModelState.IsValid)
{
返回视图(“客户端”,视图模型);
}
var client=\u clientRepository.GetClient(viewModel.Id);
if(客户端==null)
返回NotFound();
client=Mapper.Map(viewModel);
_clientRepository.Update(客户端);
var result=await_clientRepository.SaveChangesAsync();
如果(结果、成功)
{
返回操作(“索引”);
}
ModelState.AddModelError(“,result.Message”);
返回视图(“客户端”,视图模型);
}
问题是,当调用
\u clientRepository.Update(client)
时,我会收到一条错误消息,上面说:

无法跟踪实体类型“客户端”的实例,因为已在跟踪具有相同密钥的此类型的另一个实例。添加新实体时,对于大多数键类型,如果未设置键(即,如果为键属性指定了其类型的默认值),则将创建唯一的临时键值。如果要显式设置新实体的键值,请确保它们不会与现有实体或为其他新实体生成的临时值冲突。附加现有实体时,请确保只有一个具有给定键值的实体实例附加到上下文

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

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

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

但它仍然将AddressId设置为0


我缺少什么?

当您执行
Mapper.Map(viewModel)
时,AutoMapper会创建一个新的客户端对象,其ID与现有客户端对象相同

然后指示EntityFramework更新此对象图。实体框架没有跟踪您的新客户端对象,因此它将该对象附加到其内部魔法缓存/跟踪池。由于ID冲突,此操作失败。因此出现错误“无法跟踪实体类型“客户端”的实例,因为已在跟踪具有相同密钥的此类型的另一个实例”


这也是
0
AddressId的来源。Address对象也是一个全新的对象,由AutoMapper创建,该属性的值为
默认值(int)
,因为AutoMapper在创建后从未为其分配过另一个值。

是的,没错。当我加载模型并手动映射每个属性时,然后_clientRepository.SaveChangesAsync();无需使用_clientRepository.Update(客户端);,即可自行工作;。我知道我不知道如何使用AutoMapper将viewModel映射到模型。请举例说明如何将viewModel映射到模型?您可以通过执行
Mapper.map(sourceObject,destObject)
将“映射到”现有对象。这将对顶级客户有效,但我不知道它是否也适用于儿童。值得一试,我想:)这一定是个笑话,但它是有效的:)`Mapper.Map(viewModel,property);'谢谢然后我在这里找到了一篇文章,解释了两者的区别:太好了!不过要小心。如果此映射更改EntityFramework跟踪的对象的ID,或删除两个实体之间的关系,则您将遇到问题。很抱歉,直截了当,但您使用AutoMapper的方式完全错误!AutoMapper从来没有打算用于双向映射,它的作者Jimmy Bogard也从来没有一个合理的用例。当你仔细观察它时,除了懒惰之外,没有理由进行双向映射。请随意阅读这篇来自Jimmy的文章,他在这里解释了原因以及它的用途。它总是从域或持久性模型到dto或ViewModel!所以,当您从MVC操作或WebAPI调用中收到帖子时,只需像使用AutoMapper之前那样执行即可。使用ID,从数据库中获取模型,更新其字段,调用SaveChanges()(或者如果发生了某些情况,您希望回滚它,则不调用)。无论如何,您都需要验证您的数据,并且根据您的逻辑,某些字段在某些情况下不会结转(即,如果订单未包装为“包装为礼品”,则不要向订单添加“用户问候语”)这也可能对你有用:当我观看Multiple sight教程时,他们都使用它来进行双向映射。我可以看到这样做的危险。但他们也说一个动作必须最多10行。那么告诉我,如果不使用automapper,我如何保持动作10行?当我需要将超过10个属性映射回模型时?我应该传递viewmodel返回服务并在服务中进行映射?首先,这是一个指导原则,而不是一个硬性规则。如果他们在这些教程中使用AutoMapper进行双向绑定,他们也不理解该工具。你要询问该工具的作者和DDD专家吗?:P第二,我认为这些人把代码行和指令混淆了。当你把每个属性赋值在一个新行中,它仍然是一条“指令”,只是被分割成多行。此外,您可能希望阅读此主题,以避免这种尝试带来的恐惧
[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);
}