返回IEnumerable DTO,包括单个SQL SELECT中的多对多映射

时间:2018-02-21 02:01:16

标签: c# entity-framework asp.net-core automapper entity-framework-core

我正在使用Automapper从EF Core 2实体投影到DTO。我的查询返回一个IEnumerable的DTO实例。我的DTO上的一个属性是IEnumerable,它通过源实体之间的多对多关系填充。下面列出的解决方案有效,但它会产生许多单独的SQL SELECT查询。

有没有办法映射多对多,EF可以编译单SELECT个查询而不是n个查询?

TSource:

public class FilterList
{
    public int Id { get; set; }
    public ICollection<FilterListLanguage> FilterListLanguages { get; set; }
    public string Name { get; set; }
    public string ViewUrl { get; set; }
    ...
}

TDestination:

public class FilterListSummaryDto
{
    public int Id { get; set; }
    public IEnumerable<string> Languages { get; set; }
    public string Name { get; set; }
    public string ViewUrl { get; set; }
}

映射配置文件:

CreateMap<FilterList, FilterListSummaryDto>()
    .ForMember(dto => dto.Languages,
        conf => conf.MapFrom(list => list.FilterListLanguages.Select(x => x.Language.Name)));

查询:

public async Task<IEnumerable<FilterListSummaryDto>> GetAllSummariesAsync()
{
    return await filterListsDbContext.FilterLists
                                     .AsNoTracking()
                                     .OrderBy(x => x.Name)
                                     .ProjectTo<FilterListSummaryDto>()
                                     .ToListAsync();
}

执行的SQL查询示例:

...
SELECT `x.Language`.`Name`
FROM `filterlists_languages` AS `x0`
INNER JOIN `languages` AS `x.Language` ON `x0`.`LanguageId` = `x.Language`.`Id`
WHERE @_outer_Id = `x0`.`FilterListId`
Microsoft.EntityFrameworkCore.Database.Command:Information: Executed DbCommand (1ms) [Parameters=[@_outer_Id='82' (DbType = UInt16)], CommandType='Text', CommandTimeout='30']
SELECT `x.Language`.`Name`
FROM `filterlists_languages` AS `x0`
INNER JOIN `languages` AS `x.Language` ON `x0`.`LanguageId` = `x.Language`.`Id`
WHERE @_outer_Id = `x0`.`FilterListId`
Microsoft.EntityFrameworkCore.Database.Command:Information: Executed DbCommand (1ms) [Parameters=[@_outer_Id='86' (DbType = UInt16)], CommandType='Text', CommandTimeout='30']
SELECT `x.Language`.`Name`
FROM `filterlists_languages` AS `x0`
INNER JOIN `languages` AS `x.Language` ON `x0`.`LanguageId` = `x.Language`.`Id`
WHERE @_outer_Id = `x0`.`FilterListId`
Microsoft.EntityFrameworkCore.Database.Command:Information: Executed DbCommand (0ms) [Parameters=[@_outer_Id='85' (DbType = UInt16)], CommandType='Text', CommandTimeout='30']
...

0 个答案:

没有答案