Automapper,如何使这个自定义 List<KeyValuePair> 映射通用?
Automapper, how to make this custom List<KeyValuePair> mapping generic?
我得到了以下基于构造的键值对映射:
Mapper.Initialize(cfg =>
{
cfg.CreateMap<KeyValuePair<MenuTable, List<RoleTable>>,
KeyValuePair<Menu, List<Role>>>()
.ConstructUsing(x =>
new KeyValuePair<Menu, List<Role>>(
Mapper.Map<Menu>(x.Key),
Mapper.Map<List<Role>>(x.Value)
)
);
});
这样我就可以这样称呼它了:
return Mapper.Map<List<KeyValuePair<Menu, List<Role>>>>(results);
但是,这意味着我需要在有此类查询结果的任何时候执行此操作。可能超过 100 个,它们都使用默认的扁平化进行映射,只是在一个键值对集合中。我怎样才能使这个通用?我还没有完全掌握 Automapper 中的泛型。文档让我感到困惑。我不知道如何声明泛型变量。
您实际上根本不需要映射:
- 默认支持通用列表:请参阅 sample/fiddle & http://docs.automapper.org/en/stable/Lists-and-arrays.html
- KeyValuePair<,> 对象可以被 Automapper 映射,只要 Key 和 Value 对象本身可以被映射:见 sample/fiddle
唯一有用的映射是 cfg.CreateMap<MenuTable, Menu>().ForMember(...)
,以防 属性 不匹配。
Fiddle: https://dotnetfiddle.net/1UILC3
样本:
// Sample classes
public class MenuTable
{
public string MenuProp1 {get;set;}
}
public class RoleTable
{
public string RoleProp1 {get;set;}
}
public class Menu
{
public string MenuProp1 {get;set;}
}
public class Role
{
public string RoleProp1 {get;set;}
}
public class Program
{
public static void Main()
{
// Mapper config
Mapper.Initialize(cfg => {});
// sample Data
var menuTable1 = new MenuTable() {MenuProp1="Menu1"};
var menuTable2 = new MenuTable() {MenuProp1="Menu2"};
var roleTable1 = new RoleTable() {RoleProp1="Role1"};
var roleTable2 = new RoleTable() {RoleProp1="Role2"};
// Map by property name
var target = Mapper.Map<Menu>(menuTable1);
Console.WriteLine("Map by property by name: " + target.MenuProp1);
Console.WriteLine();
// result: "Map by property by name: Menu1"
// Map KeyValuePair
var kvpSource = new KeyValuePair<MenuTable, RoleTable>(menuTable1, roleTable1);
var kvpTarget = Mapper.Map<KeyValuePair<Menu, Role>>(kvpSource);
Console.WriteLine("Map KeyValuePair: " + kvpTarget.Key.MenuProp1 + " - " + kvpTarget.Value.RoleProp1);
Console.WriteLine();
// result: "Map KeyValuePair: Menu1 - Role1"
// Map List
var listSource = new List<MenuTable>() {menuTable1, menuTable2};
var listTarget = Mapper.Map<List<Menu>>(listSource);
foreach(var item in listTarget)
{
Console.WriteLine("Map List:" + item.MenuProp1);
}
Console.WriteLine();
// result:
// Map List:Menu1
// Map List:Menu2
// Combination
var combinedSource = new List<KeyValuePair<MenuTable, List<RoleTable>>>()
{
new KeyValuePair<MenuTable, List<RoleTable>>(menuTable1, new List<RoleTable>(){roleTable1}),
new KeyValuePair<MenuTable, List<RoleTable>>(menuTable2, new List<RoleTable>(){roleTable2})
};
var combinedTarget = Mapper.Map<List<KeyValuePair<Menu, List<Role>>>>(combinedSource);
foreach(var item in combinedTarget)
{
Console.WriteLine("Combined: " + item.Key.MenuProp1 + " - " + item.Value.First().RoleProp1);
}
// result:
// Combined: Menu1 - Role1
// Combined: Menu2 - Role2
}
}
我得到了以下基于构造的键值对映射:
Mapper.Initialize(cfg =>
{
cfg.CreateMap<KeyValuePair<MenuTable, List<RoleTable>>,
KeyValuePair<Menu, List<Role>>>()
.ConstructUsing(x =>
new KeyValuePair<Menu, List<Role>>(
Mapper.Map<Menu>(x.Key),
Mapper.Map<List<Role>>(x.Value)
)
);
});
这样我就可以这样称呼它了:
return Mapper.Map<List<KeyValuePair<Menu, List<Role>>>>(results);
但是,这意味着我需要在有此类查询结果的任何时候执行此操作。可能超过 100 个,它们都使用默认的扁平化进行映射,只是在一个键值对集合中。我怎样才能使这个通用?我还没有完全掌握 Automapper 中的泛型。文档让我感到困惑。我不知道如何声明泛型变量。
您实际上根本不需要映射:
- 默认支持通用列表:请参阅 sample/fiddle & http://docs.automapper.org/en/stable/Lists-and-arrays.html
- KeyValuePair<,> 对象可以被 Automapper 映射,只要 Key 和 Value 对象本身可以被映射:见 sample/fiddle
唯一有用的映射是 cfg.CreateMap<MenuTable, Menu>().ForMember(...)
,以防 属性 不匹配。
Fiddle: https://dotnetfiddle.net/1UILC3
样本:
// Sample classes
public class MenuTable
{
public string MenuProp1 {get;set;}
}
public class RoleTable
{
public string RoleProp1 {get;set;}
}
public class Menu
{
public string MenuProp1 {get;set;}
}
public class Role
{
public string RoleProp1 {get;set;}
}
public class Program
{
public static void Main()
{
// Mapper config
Mapper.Initialize(cfg => {});
// sample Data
var menuTable1 = new MenuTable() {MenuProp1="Menu1"};
var menuTable2 = new MenuTable() {MenuProp1="Menu2"};
var roleTable1 = new RoleTable() {RoleProp1="Role1"};
var roleTable2 = new RoleTable() {RoleProp1="Role2"};
// Map by property name
var target = Mapper.Map<Menu>(menuTable1);
Console.WriteLine("Map by property by name: " + target.MenuProp1);
Console.WriteLine();
// result: "Map by property by name: Menu1"
// Map KeyValuePair
var kvpSource = new KeyValuePair<MenuTable, RoleTable>(menuTable1, roleTable1);
var kvpTarget = Mapper.Map<KeyValuePair<Menu, Role>>(kvpSource);
Console.WriteLine("Map KeyValuePair: " + kvpTarget.Key.MenuProp1 + " - " + kvpTarget.Value.RoleProp1);
Console.WriteLine();
// result: "Map KeyValuePair: Menu1 - Role1"
// Map List
var listSource = new List<MenuTable>() {menuTable1, menuTable2};
var listTarget = Mapper.Map<List<Menu>>(listSource);
foreach(var item in listTarget)
{
Console.WriteLine("Map List:" + item.MenuProp1);
}
Console.WriteLine();
// result:
// Map List:Menu1
// Map List:Menu2
// Combination
var combinedSource = new List<KeyValuePair<MenuTable, List<RoleTable>>>()
{
new KeyValuePair<MenuTable, List<RoleTable>>(menuTable1, new List<RoleTable>(){roleTable1}),
new KeyValuePair<MenuTable, List<RoleTable>>(menuTable2, new List<RoleTable>(){roleTable2})
};
var combinedTarget = Mapper.Map<List<KeyValuePair<Menu, List<Role>>>>(combinedSource);
foreach(var item in combinedTarget)
{
Console.WriteLine("Combined: " + item.Key.MenuProp1 + " - " + item.Value.First().RoleProp1);
}
// result:
// Combined: Menu1 - Role1
// Combined: Menu2 - Role2
}
}