如何使用 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 IEnumerable
或 IList
等,而不是 IQueryable
,那么我的建议是将其转移到使用 IQueryable
或获取完全删除存储库,只使用 DbContext
/DbSet
s.
我使用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 IEnumerable
或 IList
等,而不是 IQueryable
,那么我的建议是将其转移到使用 IQueryable
或获取完全删除存储库,只使用 DbContext
/DbSet
s.