【问题标题】:Generically convert IQueryable list to a list of dto objects一般将 IQueryable 列表转换为 dto 对象列表
【发布时间】:2016-04-15 20:23:25
【问题描述】:

背景

我有一个将 IQueryable 列表转换为 IEnumerable 的扩展方法:

public static IEnumerable<PersonDto> ToDtoList(
    this IQueryable<Person> source)
{
    var result = new List<PersonDto>();

    foreach (var item in source)
    {
        result.Add(item.ToDto());
    }

    return result;
}

item.ToDto 扩展是这样做的:

public static PersonDto ToDto(this Person source)
{
    if (source == null)
        return null;

    return new PersonDto
    {
        PersonId = source.personId,
        Firstname = source.firstname,
        Lastname = source.lastname,
        DateOfBirth = source.dateOfBirth,
        CreateDate = source.createDate,
        ModifyDate = source.modifyDate,
    };
}

问题

有没有办法配置以下内容以使item.ToDto() 工作?

public static IEnumerable<T2> ToDtoList<T, T2>(this IQueryable<T> source)
{
    var result = new List<T2>();

    foreach (var item in source)
    {
        result.Add(item.ToDto());
    }

    return result;
}

按原样,它不起作用,因为.ToDtoitem 的不可解析符号。

【问题讨论】:

  • 您可以创建自定义界面,如IToDto。然后从那里继承所有DTO 类。并将约束添加到您的通用方法中作为` where T : IToDto`
  • IToDto Interface 是不是可以留空?

标签: c# .net web-applications asp.net-web-api


【解决方案1】:

问题(您可能知道)是如何“一般”将T 映射到T2

您可以使用AutoMapper 之类的工具,您可以将其配置为在任意两种类型之间进行一般映射,或者您可以为映射函数添加参数:

public static IEnumerable<T2> ToDtoList<T, T2>(this IQueryable<T> source, Func<T, T2> map)
{
    var result = source.AsEnumerable()  // to avoid projecting the map into the query
                       .Select(s => map(s));

    return result;
}

【讨论】:

  • Automapper 选项是理想的,但考虑到 DL 和 BL 之间(巨大的)历史差异,这并不现实。使用建议的地图功能意味着原本非常易于使用的地图工具变得更加复杂,所以我不会选择它。也就是说,您为我的问题提供了一个非常可行的答案,非常感谢!
猜你喜欢
  • 1970-01-01
  • 2020-01-10
  • 1970-01-01
  • 2013-08-14
  • 1970-01-01
  • 2013-12-02
  • 1970-01-01
  • 2014-07-12
  • 1970-01-01
相关资源
最近更新 更多