使用 CSVHelper 映射 IEnumerable 属性

Mapping an IEnumerable property with CSVHelper

我有一个User的class,可以有多个联系电话。我正在使用 CsvHelper 生成用户报告,这将创建一个包含用户姓名和联系方式的 CSV 文件。 每个联系人号码应显示在其自己的列中,联系人号码的类型作为列 header。

下面是我的 ContactNumberUser classes,以及一个 UserMap class 应该相应地格式化我的 CSV 文件:

public class ContactNumber
{
    public string ContactType { get; set; }
    public string Number { get; set; }
}

public class User
{
    public string Name { get; set; }
    public IEnumerable<ContactNumber> ContactNumbers{ get; set;}
}

public sealed class UserMap : CsvClassMap<User>
{
    public UserMap()
    {
        Map(m => m.Name).Name("Username");
        // Incorrect Code
        Map(m => m.ContactNumbers).Name(c => c.ContactType);
    }
}

我应该如何映射 ContactNumbers 的 IEnumerable 属性 以获得我想要的结果?

它不是 CsvHelper - read in multiple columns to a single list 的副本,因为这个问题问的是如何从模型转换为 CSV,而不是相反。我通过创建中间模型解决了这个问题。因此,首先将原始模型(用户)转换为中间模型(联系人),然后映射该模型并创建 CSV。

我知道这是一个老问题,但我通过将以下 属性 放在我的 DTO(用户 class)上创建了另一个解决方案。

public string ConcatenatedUserNumbers
    {
        get
        {
            if (ContactNumbers != null && ContactNumbers.Any())
            {
                return string.Join("; ", ContactNumbers.Select(a => a.Number));
            }
            return string.Empty;
        }
    }

然后我在 CsvHelper 中映射到这个 属性,就像这样:

Map(a => a.ConcatenatedUserNumbers).Name("User Numbers");

您显然可以为用户类型做同样的事情,或者有一个方法可以同时获得这两种类型。数据可能并不完美,但最终用户仍然可以在 excel 中使用 'filter' 功能,并且它是人类可读的。所有这些都不需要多余的映射等。

注意:如果这个额外的 属性 仅用于 CSV 映射,您还可以制作一个 class CSVUser : User。您可以将建议的 属性 仅放在 CSVUser 上。

我希望这对某人有所帮助。

我喜欢你的解决方案@Humble Rumble

public string ConcatenatedUserNumbers
    {
        get
        {
            if (ContactNumbers != null && ContactNumbers.Any())
            {
                return string.Join("; ", ContactNumbers.Select(a => a.Number));
            }
            return string.Empty;
        }
    }

这是一个 lambda

    public string ConcatenatedUserNumbers =>
        (this.ContactNumbers != null && this.ContactNumbers .Any())
        ? string.Join("; ", this.ContactNumbers .Select(a => a.Number))
        : string.Empty;