0

情况是我正在解析一个文件,看起来像这样。

姓名 帐户
富客户端 123
酒吧客户 456,789

在真实数据中我做了更多的事情,清理帐户等,但重点是,在 Account 列中。我现在得到一个带有 2 条记录的 IEnumerable,我想通过在 Account 列的逗号上拆分记录来获得一个带有 3 条记录的 IEnumerable。

像这样。

姓名 帐户
富客户端 123
酒吧客户 456
酒吧客户 789

这可以通过 CSV Helper 实现吗?

4

1 回答 1

1
void Main()
{
    using (var sReader = new StringReader("Name,Account\nFoo client,123\nBar client,\"456,789\""))
    using (var csvReader = new CsvHelper.CsvReader(sReader, CultureInfo.InvariantCulture))
    {
        csvReader.Read();
        csvReader.ReadHeader();
        
        var records = new List<Foo>();
        
        while (csvReader.Read())
        {
            var name = csvReader.GetField("Name");
            var account = csvReader.GetField("Account");
            
            var splitAccounts = account.Split(",");
            
            foreach(var item in splitAccounts)
            {
                records.Add(new Foo { Name = name, Account = int.Parse(item)});
            }
            
        }
        records.Dump();
    }
}

public class Foo 
{
    public string Name { get; set; }
    public int Account { get; set; }
}

更新: 每一行都是一个记录,所以你真的不能用你ClassMap的行外创建一个新记录。您可以做的是将您的类包装在另一个包含List<MyClass>您尝试创建的记录的类中,然后将它们组合回单个List<MyClass>. 如果Account可以输入stringMyClass您可以不用分开就可以逃脱,MyClassMap让它成为AutoMap()您的班级。

void Main()
{
    using (var sReader = new StringReader("Name,Account\nFoo client,123\nBar client,\"456,789\""))
    using (var csvReader = new CsvHelper.CsvReader(sReader, CultureInfo.InvariantCulture))
    {
        csvReader.Configuration.RegisterClassMap<FooMap>();
        csvReader.Configuration.RegisterClassMap<MyClassMap>();
        
        var wrappedRecords = csvReader.GetRecords<Foo>();
        
        var records = wrappedRecords.SelectMany(r => r.Clients).ToList();
        
        records.Dump();
    }
}

public class FooMap : ClassMap<Foo>
{
    public FooMap()
    {
        Map(x => x.Clients).ConvertUsing(x =>
        {
            var records = new List<MyClass>();
            
            var record = x.GetRecord<MyClass>();
            
            var splitAccounts = x.GetField("Account").Split(",");

            foreach (var item in splitAccounts)
            {
                records.Add(new MyClass { Name = record.Name, Account = int.Parse(item) });
            }
            
            return records;
        });
    }
}

public class MyClassMap : ClassMap<MyClass>
{
    public MyClassMap()
    {
        Map(x => x.Name);
    }   
}

public class Foo
{
    public List<MyClass> Clients { get; set; }
}

public class MyClass
{
    public string Name { get; set; }
    public int Account { get; set; }
}
于 2020-12-09T16:31:59.043 回答