CsvReader可以根据列数使用不同的记录类型映射吗?

问题描述 投票:0回答:1

我有一堆需要读取的CSV文件,除了添加一列外,它们都相似。本质上,旧的CSV格式有7列,而新的CSV格式有8列。一旦读取,新列将被默认/编辑,然后在写出时文件将具有8列-因此将来的读取现在将具有新列。

因此,我正在尝试执行以下CvsHelper示例:Reading Multiple Record Types

除了唯一的区别是文件中的列数-不是标识字段值。

我尝试了CsvParser在它自己的using()中使用文件第一行的单个Read()来确定列数,并认为在随后的using()中CsvReader可以为该类注册特定于计数的ClassMap CsvReader.GetRecords。但是,似乎没有一个属性或方法可以回答解析器遇到的列数。与CsvReader.Read()相同-Read()之后CsvReader.Context.ColumnCount为零。任何想法/指针表示赞赏。

更新

这是我的代码(我知道长名):

using System;
using System.Globalization;
using System.IO;
using System.Linq;
using CsvHelper;
using CsvHelper.Configuration;

namespace TopazDomain.Classes.Extensions
{
    public static class FootprintComponentMapFileExtensions
    {
        public sealed class FootprintComponentReadMapper : ClassMap<FootprintComponentMap>
        {
            public FootprintComponentReadMapper()
            {
                Map(m => m.Footprint).Index(0);
                Map(m => m.Value).Index(1);
                Map(m => m.Component).Index(2);
                Map(m => m.Head).Index(3);
                Map(m => m.CompR).Index(4);
                Map(m => m.Polarized).Index(5);
                Map(m => m.Comment).Index(6);
                Map(m => m.LibR).ConvertUsing(row =>
                {
                    if (row.TryGetField(7, out string field))
                    {
                        return field;
                    }
                    else
                    {
                        return String.Empty;
                    }
                });
            }
        }

        public sealed class FootprintComponentWriteMapper : ClassMap<FootprintComponentMap>
        {
            public FootprintComponentWriteMapper()
            {
                Map(m => m.Footprint).Index(0);
                Map(m => m.Value).Index(1);
                Map(m => m.Component).Index(2);
                Map(m => m.Head).Index(3);
                Map(m => m.CompR).Index(4);
                Map(m => m.Polarized).Index(5);
                Map(m => m.Comment).Index(6);
                Map(m => m.LibR).Index(7);
            }
        }

        public static bool ImportFootprintComponentMaps(this FootprintComponentMapFile footprintComponentMapFile,
            string filename)
        {
            bool done = false;

            using (var lineReader = new LineReader(filename))
            using (var csv = new CsvReader(lineReader, CultureInfo.InvariantCulture))
            {
                csv.Configuration.RegisterClassMap<FootprintComponentReadMapper>();

                footprintComponentMapFile.FootprintComponentMaps = csv.GetRecords<FootprintComponentMap>().ToList();

                done = true;
            }

            return done;
        }

        public static bool ExportFootprintComponentMaps(this FootprintComponentMapFile footprintComponentMapFile,
            string filename)
        {
            bool done = false;

            CsvConfiguration cvsConfiguration = new CsvConfiguration(CultureInfo.InvariantCulture);
            cvsConfiguration.HasHeaderRecord = false;

            using (var lineWriter = new StreamWriter(filename))
            using (var csv = new CsvWriter(lineWriter, cvsConfiguration))
            {
                csv.Configuration.RegisterClassMap<FootprintComponentWriteMapper>();

                csv.WriteRecords(footprintComponentMapFile.FootprintComponentMaps);

                done = true;
            }

            return done;
        }
    }
}
csvhelper csvreader
1个回答
0
投票

您可以拥有一个具有8个属性的新对象,并使用ConvertUsing有条件地映射第8列。

public class OldFoo
{
    public int Id { get; set; }
    public string FirstName { get; set; }
}

public class NewFoo 
{
    public int Id { get; set; }
    public string FirstName { get; set; }
    public string LastName { get; set; }
}

public class NewFooClassMap : ClassMap<NewFoo>
{
    public NewFooClassMap()
    {
        Map(m => m.Id).Index(0);
        Map(m => m.FirstName).Index(1);
        Map(m => m.LastName).ConvertUsing(row => {                
            if(row.TryGetField(2, out string field))
            {
                return field;
            }
            else
            {
                return null;
            }
        });
    }
}

public class Program
{
    public static void Main(string[] args)
    {
        using (MemoryStream stream = new MemoryStream())
        using (StreamWriter writer = new StreamWriter(stream))
        using (StreamReader reader = new StreamReader(stream))
        using (CsvReader csv = new CsvReader(reader, CultureInfo.InvariantCulture))
        {
            writer.WriteLine("1,Bob");
            writer.WriteLine("2,Davey");
            writer.Flush();
            stream.Position = 0;

            csv.Configuration.RegisterClassMap<NewFooClassMap>();
            csv.Configuration.HasHeaderRecord = false;

            var records = csv.GetRecords<NewFoo>().ToList();

        }

        using (MemoryStream stream = new MemoryStream())
        using (StreamWriter writer = new StreamWriter(stream))
        using (StreamReader reader = new StreamReader(stream))
        using (CsvReader csv = new CsvReader(reader, CultureInfo.InvariantCulture))
        {
            writer.WriteLine("1,Bob,Barker");
            writer.WriteLine("2,Davey,Jones");
            writer.Flush();
            stream.Position = 0;

            csv.Configuration.RegisterClassMap<NewFooClassMap>();
            csv.Configuration.HasHeaderRecord = false;

            var records = csv.GetRecords<NewFoo>().ToList();

        }
    }
}
© www.soinside.com 2019 - 2024. All rights reserved.