当外键实体属于同一类型时,AutoMapper 会忽略 MaxDepth
AutoMapper ignores MaxDepth when foreign key entity is of the same type
我试图让 AutoMapper 只映射实体的第一层,所以我设置了 MaxDepth(1),效果很好,除了我的菜单实体有一个 属性 称为 ParentMenu也是菜单类型。
Startup.cs
public IServiceProvider ConfigureServices(IServiceCollection services)
{
services
...
...
.AddAutoMapper(config =>
{
config.AddProfiles(typeof(Startup).Assembly);
config.ForAllMaps((cfg, expr) =>
{
if (typeof(Entity).IsAssignableFrom(cfg.DestinationType))
{
expr.MaxDepth(1);
}
});
config.CreateMissingTypeMaps = true;
config.ValidateInlineMaps = false;
});
...
...
}
Menu.cs
public class Menu : Entity
{
int Id {get; set;}
string Name {get; set;}
int ParentMenuId {get; set;}
Menu ParentMenu {get; set;}
int ModuleId {get; set;}
Module Module {get; set;}
}
MenuViewModel.cs
public class MenuViewModel
{
int Id {get; set;}
string Name {get; set;}
int ParentMenuId {get; set;}
string ParentMenuName {get; set;}
int ModuleId {get; set;}
string ModuleName {get; set;}
}
MenuController.cs
public IActionResult Edit(MenuViewModel viewModel)
{
var model = EditGetModel(id); // returns the Menu Entity
Mapper.Map(viewModel, model);
// model.ParentMenuId is set properly
// model.ParentMenu set to a new instance of Menu ignoring MaxDepth(1)
// model.ModuleId is set properly
// model.Module is properly left null
...
...
}
我不明白为什么 MaxDepth(1) 在实体具有相同类型的 属性 时被忽略,任何帮助将不胜感激。
这似乎与深度或递归没有任何关系。也不清楚确切的问题是什么。您拥有的代码是将视图模型映射到实体。如果我不得不猜测,我想问题是 AutoMapper 正在创建一个新的 Menu
实例并用它替换实体上现有的 ParentMenu
属性。原因是您正在投影 ParentMenuName
,它将映射到实体上的 ParentMenu.Name
。您应该忽略映射中的 ParentMenu
:
CreateMap<MenuViewModel, Menu>()
...
.ForMember(dest => dest.ParentMenu, opts => opts.Ignore());
我试图让 AutoMapper 只映射实体的第一层,所以我设置了 MaxDepth(1),效果很好,除了我的菜单实体有一个 属性 称为 ParentMenu也是菜单类型。
Startup.cs
public IServiceProvider ConfigureServices(IServiceCollection services)
{
services
...
...
.AddAutoMapper(config =>
{
config.AddProfiles(typeof(Startup).Assembly);
config.ForAllMaps((cfg, expr) =>
{
if (typeof(Entity).IsAssignableFrom(cfg.DestinationType))
{
expr.MaxDepth(1);
}
});
config.CreateMissingTypeMaps = true;
config.ValidateInlineMaps = false;
});
...
...
}
Menu.cs
public class Menu : Entity
{
int Id {get; set;}
string Name {get; set;}
int ParentMenuId {get; set;}
Menu ParentMenu {get; set;}
int ModuleId {get; set;}
Module Module {get; set;}
}
MenuViewModel.cs
public class MenuViewModel
{
int Id {get; set;}
string Name {get; set;}
int ParentMenuId {get; set;}
string ParentMenuName {get; set;}
int ModuleId {get; set;}
string ModuleName {get; set;}
}
MenuController.cs
public IActionResult Edit(MenuViewModel viewModel)
{
var model = EditGetModel(id); // returns the Menu Entity
Mapper.Map(viewModel, model);
// model.ParentMenuId is set properly
// model.ParentMenu set to a new instance of Menu ignoring MaxDepth(1)
// model.ModuleId is set properly
// model.Module is properly left null
...
...
}
我不明白为什么 MaxDepth(1) 在实体具有相同类型的 属性 时被忽略,任何帮助将不胜感激。
这似乎与深度或递归没有任何关系。也不清楚确切的问题是什么。您拥有的代码是将视图模型映射到实体。如果我不得不猜测,我想问题是 AutoMapper 正在创建一个新的 Menu
实例并用它替换实体上现有的 ParentMenu
属性。原因是您正在投影 ParentMenuName
,它将映射到实体上的 ParentMenu.Name
。您应该忽略映射中的 ParentMenu
:
CreateMap<MenuViewModel, Menu>()
...
.ForMember(dest => dest.ParentMenu, opts => opts.Ignore());