Может ли CsvReader использовать разные карты типов записей в зависимости от количества столбцов? - PullRequest
0 голосов
/ 25 апреля 2020

У меня есть куча CSV-файлов, которые мне нужно прочитать, которые похожи за исключением добавления столбца. По сути, старый формат CSV имеет 7 столбцов, а новый - 8. Нет заголовков. После прочтения новый столбец будет установлен по умолчанию / отредактирован, а затем файл будет иметь 8 столбцов при записи - поэтому при будущих чтениях теперь будет новый столбец.

Так что я пытаюсь сделать что-то вроде этого CvsHelper пример: Чтение нескольких типов записей

, за исключением единственного различия в количестве столбцов в файле, а не в значении идентифицирующего поля.

Я попытался использовать CsvParser в его собственные с помощью () с одним Read () первой строки файла, чтобы определить количество столбцов с идеей, что CsvReader при последующем использовании () может зарегистрировать счетчик, определяющий c ClassMap для CsvReader.GetRecords. Однако не существует свойства или метода, который бы отвечал на количество столбцов, с которыми столкнулся анализатор. То же самое с CsvReader.Read () - CsvReader.Context.ColumnCount равен нулю после Read (). Любые идеи / указатели приветствуются.

Обновление

Вот мой пересмотренный код (длинные имена, я знаю) - спасибо за предложение Дэвид:

namespace TopazDomain.Classes
{
    public class FootprintComponentMap : Entity<int>
    {
        private const int footprintWidth = 40;
        [StringLength(footprintWidth)]
        public string Footprint { get; set; }

        private const int valueWidth = 40;
        [StringLength(valueWidth)]
        public string Value { get; set; }

        public int Component { get; set; }

        public int Head { get; set; }

        private const int rotationWidth = 9;
        [StringLength(rotationWidth)]
        public string CompR { get; set; }

        private const int polarizedWidth = 2;
        [StringLength(polarizedWidth)]
        public string Polarized { get; set; }

        private const int commentWidth = 40;
        public string Comment { get; set; }

        [StringLength(rotationWidth)]
        public string LibR { get; set; }

        // navigation
        [Required]
        public FootprintComponentMapFile FootprintComponentMapFile { get; set; }

        public FootprintComponentMap()
        {
            Footprint = String.Empty;
            Value = String.Empty;
            Component = 0;
            Head = 0;
            CompR = "0.00";
            Polarized = "N";
            Comment = String.Empty;
            LibR = "0.00";
        }

        public FootprintComponentMap(FootprintComponentMap footprintComponentMap) : this()
        {
            Footprint = footprintComponentMap.Footprint;
            Value = footprintComponentMap.Value;
            Component = footprintComponentMap.Component;
            Head = footprintComponentMap.Head;
            CompR = footprintComponentMap.CompR;
            Polarized = footprintComponentMap.Polarized;
            Comment = footprintComponentMap.Comment;
            LibR = footprintComponentMap.LibR;
        }

        public FootprintComponentMap(string footprint, string value, int componentNumber, int headNumber, string componentR,
            string polarized, string libraryR, string comment) : this()
        {
            Footprint = footprint;
            Value = value;
            Component = componentNumber;
            Head = headNumber;
            CompR = componentR;
            Polarized = polarized;
            Comment = comment;
            LibR = libraryR;
        }
    }
}

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;
        }
    }
}

1 Ответ

0 голосов
/ 25 апреля 2020

У вас может быть новый объект с 8 свойствами и условно сопоставить 8-й столбец с ConvertUsing.

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();

        }
    }
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...