2016-03-03 185 views
4

在MVC应用程序中做同样的实体类型的副本,但是希望忽略复制主键(对现有实体进行更新)。但在下面的地图中将Id列设置为忽略不起作用,并且Id被覆盖。AutoMapper ForMember忽略不工作

cfg.CreateMap<VendorContact, VendorContact>() 
    .ForMember(dest => dest.Id, option => option.Ignore()) 
    .ForMember(dest => dest.CreatedById, option => option.Ignore()) 
    .ForMember(dest => dest.CreatedOn, option => option.Ignore()) 
    ; 

执行映射:

existingStratusVendorContact = Mapper.Map<VendorContact>(vendorContact); 

this other answer,但现在看来,我这样做了。

UPDATE:

据透露,我创造我的地图在Global.asax像这样:

Mapper.Initialize(cfg => 
{ 
    cfg.CreateMap<VendorContact, VendorContact>() 
     .ForMember(dest => dest.Id, option => option.Ignore()) 
     .ForMember(dest => dest.CreatedById, option => option.Ignore()) 
     .ForMember(dest => dest.CreatedOn, option => option.Ignore()) 
     ; 

}); 
+0

'existingStratusVendorContact'是一个现有的对象,你想替换除'Id','CreatedById','CreatedOn'之外的属性吗?或者用这个属性的默认值创建一个新的? –

+0

是的,前者。更新除这3个属性以外的现有对象。 –

回答

2

你的问题是你没有给automapper现有的对象。 Automapper绝对可以做到这一点。

Mapper.Map<VendorContact>(vendorContact, existingStratusVendorContact); 

应该做你想做的。您目前的代码正在创建一个全新的对象,并用全新的对象替换existingStratusVendorContact。如您所料,上述代码将采用现有的对象和更新值。

+0

谢谢。这似乎是工作,但后来我试图保存existingStratusVendorContact时出现错误。 '操作失败:'该关系无法更改,因为一个或多个外键属性不可空。当对关系进行更改时,相关的外键属性将设置为空值。 ...'当我在保存时查看该实体时,它看起来像所有的外键都在调试器中填充...所以不知道发生了什么。关于实体框架如何处理我想的东西。 –

+0

知道了!我的最后一个问题是我如何检索要更新的实体。当我改变它以获得它.AsNoTracking ...然后它工作。 –

0

UPDATE:

问题是,当你分配给Mapper.Map<VendorContact>(vendorContact);existingStratusVendorContact正在用Map()方法替换变量的当前值,而不管你忽略了哪些属性。

With Mapper.Map(source)根据一些惯例,您可以将对象投影到其他类型复制属性的新对象,但是您正在创建一个新对象。

在您的代码中,您正在使用其默认值创建具有Id,CreatedByIdCreatedOn属性的新对象。

您可以使用Mapper.Map(source, destination)重载,不正是你想要什么:

Mapper.Map<VendorContact>(vendorContact, existingStratusVendorContact); 

ORIGINAL:

如果您要创建这样您的地图:

var cfg = new MapperConfiguration(c => 
{ 
    c.CreateMap<VendorContact, VendorContact>() 
     .ForMember(dest => dest.Id, option => option.Ignore()) 
     .ForMember(dest => dest.CreatedById, option => option.Ignore()) 
     .ForMember(dest => dest.CreatedOn, option => option.Ignore()); 
}); 

您需要使用此配置创建映射器:

var mapper = cfg.CreateMapper(); 

,并使用它的对象映射:

var existingStratusVendorContact = mapper.Map<VendorContact>(vendorContact); 

如果使用静态类Mapper默认行为是用来和属性映射。

+0

@ArturoMechaca谢谢阿图罗。看到我更新的问题,指出我如何创建地图。这是如何影响你的答案的?另外,这就是我在使用AutoMapper 3的解决方案中的另一个项目中所做的工作。但是,此新项目使用的是AutoMapper 4.所以,可能会更改首选Map创建方法/语法? –

+0

@ArturoMechaca这是错误的,请参阅https://github.com/AutoMapper/AutoMapper/blob/develop/src/AutoMapper/Mapper.cs#L140'映射的目标对象,与 object' –

+0

@ChadRichardson:找到一种方法可以用Automapper来完成。感谢Tomas –