如何使用 AutoMapper 映射 Select

How Can I Map Select With AutoMapper

我使用AutoMapper 来作图。我需要使用 Distinct & Select。但现在我的映射不起作用,并显示“缺少类型映射配置或不支持的映射”

我能做什么?

        cfg.CreateMap<SearchHistory, SearchDashBoardDto>();

        var searchList = _unitOfWork.SearchRepository.GetSearchHistory(userId, sessionId)
                                .Select(x => new { x.SearchText, x.Url })
                                .Distinct();

        return _mapper.Map<List<SearchDashBoardDto>>(searchList);

这应该有效。

_unitOfWork.SearchRepository.GetSearchHistory(userId, sessionId)
                                .Select(x => new { x.SearchText, x.Url })
                                .Distinct()
                                .Select(s => _mapper.Map<SearchDashBoardDto>(s))
                                .ToList()

您正在尝试将匿名类型映射到 DTO。旧版本的 Automapper 将通过选项支持这一点,以尝试解决未知映射,但逐渐被淘汰。我相信仍然支持 DynamicMap() 应该工作 /w Dmitriy 的回答。

Automapper 可以使用 ProjectTo 完全管理它。您将需要为其提供一个 MapperConfiguration 以及如何将 SearchHistory 转换为 SearchDashBoardDto, 确保您的搜索存储库 returning IQueryable<SearchHistory> 而不是类似IEnumerable<SearchHistory>.

假设您的 DTO 有一个 SearchText 和 Url 列,其命名约定与实体相同,本地配置示例:

var config = new MapperConfiguration(cfg => cfg.CreateMap<SearchHistory, SearchDashBoardDto>());

var searchList = _unitOfWork.SearchRepository
    .GetSearchHistory(userId, sessionId)
    .ProjectTo<SearchDashBoardDto>(config)
    .Distinct()
    .ToList();

ProjectTo 扩展方法需要映射器配置。这可以集中配置并作为依赖项传递,或者按需构建或通过工厂方法。 (我通常将它们作为静态方法放在视图模型上)

编辑:或者,如果您遇到使用 Select 匿名类型的麻烦,您也可以只填充您的 ViewModel:

var searchList = _unitOfWork.SearchRepository.GetSearchHistory(userId, sessionId)
    .Select(x => new SearchDashBoardDto
    { 
        SearchText = x.SearchText, 
        Url = x.Url 
    }).Distinct()
    .ToList();

如果你的存储库是 returning IEnumerable<SearchHistory> 或类似的,这将不起作用,并且从性能的角度来看它肯定不会像 return 那样理想ing 整个搜索历史实体。 (你只关心 2 个字段和不同的结果)以上可以帮助构建更高效的查询,让数据库调用 return 只是你想要 return 的数据。如果存储库是 returning IEnumerableIList 等,而不是 IQueryable,那么我的建议是将其转移到使用 IQueryable 或获取完全删除存储库,只使用 DbContext/DbSets.