如何在不指定每个成员字段的情况下从元组映射?
How to map from a tuple without specifying each member field?
给定以下示例 类
public class User
{
public string Username { get; set; }
public string FieldFromUser { get; set; }
}
public class Todo
{
public string Title { get; set; } // !! map this one to UsernameWithTodoTitle.TodoTitle !!
public string FieldFromTodo { get; set; }
}
public class UsernameWithTodoTitle
{
public string Username { get; set; }
public string TodoTitle { get; set; } // !! this field represents Todo.Title !!
public string FieldFromUser { get; set; }
public string FieldFromTodo { get; set; }
}
我想将用户和待办事项映射到 UsernameWithTodoTitle
。为了解决这个问题,我使用了 packages
AutoMapper v10.1.1
AutoMapper.Extensions.Microsoft.DependencyInjection v8.1.1
当处理多个来源时,这个解决方案对我来说很好用:
public class UsernameWithTodoTitleMappingProfile : Profile
{
public UsernameWithTodoTitleMappingProfile()
{
CreateMap<(User, Todo), UsernameWithTodoTitle>()
.ForMember(
destination => destination.Username,
memberOptions => memberOptions.MapFrom(source => source.Item1.Username))
.ForMember(
destination => destination.TodoTitle,
memberOptions => memberOptions.MapFrom(source => source.Item2.Title))
.ForMember(
destination => destination.FieldFromUser,
memberOptions => memberOptions.MapFrom(source => source.Item1.FieldFromUser))
.ForMember(
destination => destination.FieldFromTodo,
memberOptions => memberOptions.MapFrom(source => source.Item2.FieldFromTodo));
}
}
所以我可以像这样映射用户和待办事项
var usernameWithTodoTitle = _mapper.Map<UsernameWithTodoTitle>((user, todo));
因为我使用的是元组,所以我必须指定每个字段,因为显然 Automapper 在处理元组时不知道在哪里搜索这些字段。唯一不同的字段名称是 Todo.Title
和 UsernameWithTodoTitle.TodoTitle
。我想知道我是否可以简化映射配置文件,也许我什至不必使用元组?以下配置文件只是我想要实现的伪实现
public class UsernameWithTodoTitleMappingProfile : Profile
{
public UsernameWithTodoTitleMappingProfile()
{
CreateMap<(User, Todo), UsernameWithTodoTitle>()
// map all fields by name as expected and ...
.ForMember(
destination => destination.TodoTitle,
memberOptions => memberOptions.MapFrom(source => source.Item2.Title));
}
}
正如您已经提到的,您不需要使用 Tuple
- 如果确实需要,请参阅下面的更新。
您可以映射来自多个源的单个目标对象。
设置从源 User
和 Todo
到 UsernameWithTodoTitle
目标的常规映射。
CreateMap<User, UsernameWithTodoTitle>()
CreateMap<Todo, UsernameWithTodoTitle>()
.ForMember(
destination => destination.TodoTitle,
memberOptions => memberOptions.MapFrom(source => source.Title)
);
要实例化一个 UsernameWithTodoTitle
对象,应用两个映射之一;来自 User
.
var usernameWithTodoTitle = _mapper.Map<UsernameWithTodoTitle>(user);
其次,您通过应用下一个映射来更新新创建的 UsernameWithTodoTitle
;来自 Todo
.
_mapper.Map(todo, usernameWithTodoTitle);
更新
如果你真的want/need那个Tuple
映射,这样的映射可以如下设置,通过Tuple
部分的IncludeMembers
规则将触发相应的映射。
这使得仍然需要上面的单独映射规则。
CreateMap<(User, Todo), UsernameWithTodoTitle>()
.IncludeMembers(o => o.Item1, o => o.Item2);
您可能更喜欢命名为 Tuple
的部分。
CreateMap<(User User, Todo Todo), UsernameWithTodoTitle>()
.IncludeMembers(o => o.User, o => o.Todo);
完整示例:
CreateMap<User, UsernameWithTodoTitle>();
CreateMap<Todo, UsernameWithTodoTitle>()
.ForMember(
destination => destination.TodoTitle,
memberOptions => memberOptions.MapFrom(source => source.Title)
);
CreateMap<(User User, Todo Todo), UsernameWithTodoTitle>()
.IncludeMembers(o => o.User, o => o.Todo);
var user = new User { Username = "alfki" };
var todo = new Todo { Title = "work" };
var usernameWithTodoTitle = _mapper.Map<UsernameWithTodoTitle>((user, todo));
Console.WriteLine(usernameWithTodoTitle.Username); // alfki
Console.WriteLine(usernameWithTodoTitle.TodoTitle); // work
给定以下示例 类
public class User
{
public string Username { get; set; }
public string FieldFromUser { get; set; }
}
public class Todo
{
public string Title { get; set; } // !! map this one to UsernameWithTodoTitle.TodoTitle !!
public string FieldFromTodo { get; set; }
}
public class UsernameWithTodoTitle
{
public string Username { get; set; }
public string TodoTitle { get; set; } // !! this field represents Todo.Title !!
public string FieldFromUser { get; set; }
public string FieldFromTodo { get; set; }
}
我想将用户和待办事项映射到 UsernameWithTodoTitle
。为了解决这个问题,我使用了 packages
AutoMapper v10.1.1
AutoMapper.Extensions.Microsoft.DependencyInjection v8.1.1
当处理多个来源时,这个解决方案对我来说很好用:
public class UsernameWithTodoTitleMappingProfile : Profile
{
public UsernameWithTodoTitleMappingProfile()
{
CreateMap<(User, Todo), UsernameWithTodoTitle>()
.ForMember(
destination => destination.Username,
memberOptions => memberOptions.MapFrom(source => source.Item1.Username))
.ForMember(
destination => destination.TodoTitle,
memberOptions => memberOptions.MapFrom(source => source.Item2.Title))
.ForMember(
destination => destination.FieldFromUser,
memberOptions => memberOptions.MapFrom(source => source.Item1.FieldFromUser))
.ForMember(
destination => destination.FieldFromTodo,
memberOptions => memberOptions.MapFrom(source => source.Item2.FieldFromTodo));
}
}
所以我可以像这样映射用户和待办事项
var usernameWithTodoTitle = _mapper.Map<UsernameWithTodoTitle>((user, todo));
因为我使用的是元组,所以我必须指定每个字段,因为显然 Automapper 在处理元组时不知道在哪里搜索这些字段。唯一不同的字段名称是 Todo.Title
和 UsernameWithTodoTitle.TodoTitle
。我想知道我是否可以简化映射配置文件,也许我什至不必使用元组?以下配置文件只是我想要实现的伪实现
public class UsernameWithTodoTitleMappingProfile : Profile
{
public UsernameWithTodoTitleMappingProfile()
{
CreateMap<(User, Todo), UsernameWithTodoTitle>()
// map all fields by name as expected and ...
.ForMember(
destination => destination.TodoTitle,
memberOptions => memberOptions.MapFrom(source => source.Item2.Title));
}
}
正如您已经提到的,您不需要使用 Tuple
- 如果确实需要,请参阅下面的更新。
您可以映射来自多个源的单个目标对象。
设置从源 User
和 Todo
到 UsernameWithTodoTitle
目标的常规映射。
CreateMap<User, UsernameWithTodoTitle>()
CreateMap<Todo, UsernameWithTodoTitle>()
.ForMember(
destination => destination.TodoTitle,
memberOptions => memberOptions.MapFrom(source => source.Title)
);
要实例化一个 UsernameWithTodoTitle
对象,应用两个映射之一;来自 User
.
var usernameWithTodoTitle = _mapper.Map<UsernameWithTodoTitle>(user);
其次,您通过应用下一个映射来更新新创建的 UsernameWithTodoTitle
;来自 Todo
.
_mapper.Map(todo, usernameWithTodoTitle);
更新
如果你真的want/need那个Tuple
映射,这样的映射可以如下设置,通过Tuple
部分的IncludeMembers
规则将触发相应的映射。
这使得仍然需要上面的单独映射规则。
CreateMap<(User, Todo), UsernameWithTodoTitle>()
.IncludeMembers(o => o.Item1, o => o.Item2);
您可能更喜欢命名为 Tuple
的部分。
CreateMap<(User User, Todo Todo), UsernameWithTodoTitle>()
.IncludeMembers(o => o.User, o => o.Todo);
完整示例:
CreateMap<User, UsernameWithTodoTitle>();
CreateMap<Todo, UsernameWithTodoTitle>()
.ForMember(
destination => destination.TodoTitle,
memberOptions => memberOptions.MapFrom(source => source.Title)
);
CreateMap<(User User, Todo Todo), UsernameWithTodoTitle>()
.IncludeMembers(o => o.User, o => o.Todo);
var user = new User { Username = "alfki" };
var todo = new Todo { Title = "work" };
var usernameWithTodoTitle = _mapper.Map<UsernameWithTodoTitle>((user, todo));
Console.WriteLine(usernameWithTodoTitle.Username); // alfki
Console.WriteLine(usernameWithTodoTitle.TodoTitle); // work