You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何使用AutoMapper将GameVM的HashSet<string>映射到Game实体的GameGenres?

AutoMapper映射问题解决方案

实体类与ViewModel定义

实体类

public class Game
{
    public int Id { get; set; }
    public string GameName { get; set; }
    public int DeveloperStudioId { get; set; }
    public DeveloperStudio DeveloperStudio { get; set; }
    public ICollection<GameGenre> GameGenres { get; set; }
}

public class DeveloperStudio
{
    public int Id { get; set; }
    public string Name { get; set; }
}

public class Genre
{
    public int GenreId { get; set; }
    public string GenreName { get; set; }
    public ICollection<GameGenre> GameGenres { get; set; }
}

public class GameGenre
{
    public int GameId { get; set; }
    public Game Game { get; set; }
    public int GenreId { get; set; }
    public Genre Genre { get; set; }
}

ViewModel类

public class GameVM
{
    public string GameName { get; set; }
    public string DeveloperStudioName { get; set; }
    public HashSet<string> Genres { get; set; }
}

问题说明

需要将GameVM中HashSet<string>类型的Genres属性,映射到Game实体的ICollection<GameGenre>集合中,让每个GameGenre元素的Genre.GenreName对应Genres中的字符串。原配置尝试通过Select投影赋值,无法生效。

正确配置方案

1. 配置子类型映射

首先定义string到GameGenre的映射,告诉AutoMapper如何将单个流派名称字符串转换为GameGenre对象:

CreateMap<string, GameGenre>()
    .ForMember(dest => dest.Genre, opt => opt.MapFrom(src => new Genre { GenreName = src }));

2. 配置主映射(GameVM → Game)

接着配置主映射,直接将GameVM.Genres映射到Game.GameGenres,AutoMapper会自动使用上面的子映射处理集合中的每个元素:

CreateMap<GameVM, Game>()
    // 映射游戏名称
    .ForMember(dest => dest.GameName, opt => opt.MapFrom(src => src.GameName))
    // 映射开发商信息(若需要后续匹配Id,可在此处结合仓储查询)
    .ForMember(dest => dest.DeveloperStudio, opt => opt.MapFrom(src => new DeveloperStudio { Name = src.DeveloperStudioName }))
    // 映射流派集合
    .ForMember(dest => dest.GameGenres, opt => opt.MapFrom(src => src.Genres));

原配置失效原因

原代码中dest=>dest.GameGenres.Select(s=>s.Genre.GenreName)是一个LINQ投影,并非Game实体上可直接赋值的成员属性,AutoMapper无法对这种投影结果进行赋值操作。正确的做法是直接映射GameGenres集合本身,通过子映射定义集合内元素的转换规则。

进阶:结合数据库查询流派Id

如果需要从数据库中获取对应流派的GenreId(而非仅创建新的Genre对象),可以在映射时引入仓储服务,通过流派名称查询完整的Genre实体:

// 假设已注入流派仓储
private readonly IGenreRepository _genreRepository;

CreateMap<GameVM, Game>()
    .ForMember(dest => dest.GameGenres, opt => opt.MapFrom(src => 
        src.Genres.Select(genreName => 
            new GameGenre { 
                Genre = _genreRepository.GetByGenreName(genreName) 
            })));

内容的提问来源于stack exchange,提问作者Aleksandr

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.22 00:28:33