【问题标题】:CsvHelper - Read multiple related columns into a list of objectsCsvHelper - 将多个相关列读入对象列表
【发布时间】:2020-01-14 17:50:11
【问题描述】:

我有一个这样的 CSV:(注意:实际的 csv 有 5 个重复的列,而不是只有 2 个

Id Name Diagnosis 1 Diagnosis 2 Drug 1 Drug 2 How Taken 1 How Taken 2
== ==== =========== =========== ====== ====== =========== ===========
 1 One  F23         F25         D1     D55    Oral        Inject
 2 Two  F30                     D5     D7     Inject      Inhale

我正在使用 CsvHelper 将其映射到我的 POCO 对象中,如下所示:

public class Episode {
    public int Id {get; set;}
    public string Name {get; set;}
    public IList<string> Diagnoses {get; set;}
    public IList<Drug> Drugs { get; set;}
}

public class Drug {
    public int Id {get; set;}
    public string Name {get; set;}
    public string AdministrationMethod {get; set;}
}

我已经看到了一些关于使用 CsvHelper 映射到 IEnumerable 的参考,但没有关于它的正式文档。

有什么办法:

  1. 将诊断 1、诊断 2 等映射到 IList&lt;string&gt; Diagnoses 属性?
  2. 将 [Drug x, How Taken x] 对映射到 IList&lt;Drug&gt; Drugs 属性?

以下内容与我所知道的一样接近(绝对行不通,但试图帮助给出我所追求的概念)。

void Main()
{
    using (var reader = new StreamReader("path\\to\\file.csv"))
    using (var csv = new CsvReader(reader))
    {
        csv.Configuration.RegisterClassMap<EpisodeMap>();
        var records = csv.GetRecords<EpisodeMap>();
    }
}

public EpisodeMap : ClassMap<Episode>{
    public EpisodeMap(){
      Map(m => m.Name).Name("Name");
      Map(m => m.Diagnoses).Name("Diagnosis").Index(5);  //Unsure how to indicate appropriate name "Diagnosis {index}"
      References<DrugMap>(m => m.Drugs).Index(5); //?? Not sure if something like this is possible
    }
}

public DrugMap : ClassMap<Drug> {
    public DrugMap() {
       Map(m => m.Name).Name("Drug");
       Map(m => m.AdministrationMethod).Name("How Taken");
}

【问题讨论】:

    标签: .net csvhelper


    【解决方案1】:

    不幸的是,Index() 仅适用于简单的 IEnumerable,例如 IEnumerable&lt;string&gt;。对于更复杂的对象,您将需要使用ConvertUsing(),或者使用列的名称或索引。 Name() 应该为 Diagnosis 工作,但由于某种原因,如果标题列与属性 Diagnoses 命名相同,我只能让它工作。

    您也可以使用ConvertUsing() 来获取Diagnosis 标题。

    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, new Configuration()))
            {
                writer.WriteLine("Id,Name,Diagnoses 1,Diagnoses 2,Drug 1,Drug 2,How Taken 1,How Taken 2");
                writer.WriteLine("1,One,F23,F25,D1,D55,Oral,Inject");
                writer.WriteLine("2,Two,F30,,D5,D7,Inject,Inhale");
                writer.Flush();
                stream.Position = 0;
                reader.BaseStream.Position = 0;
    
                csv.Configuration.RegisterClassMap<EpisodeMap>();
                csv.Configuration.PrepareHeaderForMatch = (header, index) => Regex.Replace(header, " ", string.Empty);
    
                var records = csv.GetRecords<Episode>().ToList();
            }
    
            Console.ReadKey();
        }
    }
    
    public class EpisodeMap : ClassMap<Episode>
    {
        public EpisodeMap()
        {
            Map(m => m.Id);
            Map(m => m.Name);
            Map(m => m.Diagnoses).Index(2,3);  //Unsure how to indicate appropriate name "Diagnosis {index}"
            Map(m => m.Drugs).ConvertUsing(row =>
            {
                return new List<Drug>
                {
                    new Drug { Name = row["Drug1"], AdministrationMethod = row["HowTaken1"] },
                    new Drug { Name = row["Drug2"], AdministrationMethod = row["HowTaken2"]}
                };
            });
        }
    }
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多