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将忽略MaxDepth_C#_Asp.net Core_Entity Framework Core_Automapper - Fatal编程技术网

C# 当外键实体的类型相同时,AutoMapper将忽略MaxDepth

C# 当外键实体的类型相同时,AutoMapper将忽略MaxDepth,c#,asp.net-core,entity-framework-core,automapper,C#,Asp.net Core,Entity Framework Core,Automapper,我试图让AutoMapper只映射实体的第一级,所以我设置了MaxDepth(1),这非常有效,除了我的菜单实体,它有一个名为ParentMenu的属性,也是菜单类型 Startup.cs public IServiceProvider ConfigureServices(IServiceCollection services) { services ... ... .AddAutoMapper(config => {

我试图让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;
      });
   ...
   ...
}
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;}
}
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;}
}
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
  ...
  ...
}
菜单.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;
      });
   ...
   ...
}
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;}
}
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;}
}
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
  ...
  ...
}
MenuViewModel.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;
      });
   ...
   ...
}
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;}
}
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;}
}
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
  ...
  ...
}
MenuController.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;
      });
   ...
   ...
}
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;}
}
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;}
}
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正在创建一个新的
菜单
实例,并用它替换实体上现有的
父菜单
属性。原因是您正在投影
ParentMenuName
,它将映射到实体上的
ParentMenu.Name
。您应该忽略映射中的父菜单:

CreateMap<MenuViewModel, Menu>()
    ...
    .ForMember(dest => dest.ParentMenu, opts => opts.Ignore());
CreateMap()
...
.FormMember(dest=>dest.ParentMenu,opts=>opts.Ignore());

MaxDepth(1)对模块属性的作用与预期的一样,只是当属性的类型和映射的实体相同时,它就不起作用了。关键是,您没有映射任何会导致任何类型的递归甚至一开始就有关系的东西。您的视图模型是一个100%平面模型,与任何其他模型都不相关。根据您发布的代码,视图模型是您的源代码,因此这只是一个直接的投影映射。它是指映射源对象的深度。这与目的地无关。视图模型没有标高,因此“最大深度”根本不适用于此处。正如我在回答中所说,正在创建一个新的
菜单
实例,因为
ParentMenuName
正在投影到
ParentMenu.Name
,AutoMapper必须实例化
ParentMenu
,以设置它。AutoMapper假设ParentMenuId应该映射到ParentMenu.Id,对于映射到Module.Id的ModuleId也是如此;如果我没有设置MaxDepth(1),那么ParentMenu.Id和Module.Id都会被设置;但是,当设置MaxDepth(1)时,不会设置Module.Id,因为它遵守MaxDepth(1)设置,但是,当ParentMenu.Id的行为应与模块相同时,会映射它;当属性为相同类型时,似乎存在问题。不管ViewModel是否是平面的,Automapper都会根据名称对映射进行假设;因此使用了MaxDepth(1)。未映射该Id,因为目标(
ParentMenuId
)上有一个具有该名称的文本属性,因此它不需要投影到
ParentMenu
。没有
ParentMenuName
属性,因此它会投影到
ParentMenu.Name
。最大深度与此无关。