【问题标题】:CsvHelper PrepareHeaderForMatch returns Context as one-item arrayCsvHelper PrepareHeaderForMatch 将 Context 作为一项数组返回
【发布时间】:2020-01-14 05:26:00
【问题描述】:

一直在使用 CsvHelper 版本 6.0.0,决定升级到最新版本(当前为 12.3.2),发现它使用了另一个参数,csv.Configuration.PrepareHeaderForMatch 的 lambda 中的索引,(Func<string,int,string>)。

v6.0.0 的代码如下所示:

csv.Configuration.PrepareHeaderForMatch = header => Regex.Replace(header, @"\/", string.Empty);

对于上一行,IReadingContext.Record 返回一个包含多条记录的数组,每列一条记录。

v12.3.2 的代码如下所示:

csv.Configuration.PrepareHeaderForMatch = (header, index) => Regex.Replace(header, @"\/", string.Empty);

但是ReadingContext.Record 现在返回一个数组,其中所有列都在一条记录中。两个版本使用完全相同的文件。尝试弄乱 lambda,但结果是一样的。如何获取Records 数组中的列?

提前致谢!

【问题讨论】:

    标签: c# csvhelper


    【解决方案1】:

    更新 - 这是自 6.0.0 版以来已更改的分隔符问题。默认分隔符现在使用CultureInfo.CurrentCulture.TextInfo.ListSeparator。因为我在美国,所以我的ListSeparator,,所以这两个例子都对我有用。对于许多国家/地区,ListSeparator;,这就是为什么对于 12.3.2 版,只有 1 列用于 @dzookatz。解决方法是在配置中指定分隔符。

    csv.Configuration.PrepareHeaderForMatch = header => Regex.Replace(header, @"\/", string.Empty);
    csv.Configuration.Delimiter = ",";
    

    我一定错过了什么。无论使用 6.0.0 版还是 12.3.2 版,var record 都会得到相同的结果。我猜你的数据还有更多我没有看到的情况。

    版本 6.0.0

    class Program
    {
        static void Main(string[] args)
        {
            var fooString = $"Id,First/Name{Environment.NewLine}1,David";
    
            using (var reader = new StringReader(fooString))
            using (var csv = new CsvReader(reader))
            {
                csv.Configuration.PrepareHeaderForMatch = header => Regex.Replace(header, @"\/", string.Empty);
    
                csv.Read();
                csv.ReadHeader();
    
                while (csv.Read())
                {
                    var record = csv.Context.Record;
                }
            }
        }
    }
    
    public class Foo
    {
        public int Id { get; set; }
        public string FirstName { get; set; }
    }
    

    版本 12.3.2

    public class Program
    {
        public static void Main(string[] args)
        {
            var fooString = $"Id,First/Name{Environment.NewLine}1,David";
    
            using (var reader = new StringReader(fooString))
            using (var csv = new CsvReader(reader))
            {
                csv.Configuration.PrepareHeaderForMatch = (header, index) => Regex.Replace(header, @"\/", string.Empty);
    
                csv.Read();
                csv.ReadHeader();
    
                while (csv.Read())
                {
                    var record = csv.Context.Record;
                }
            }
        }
    }
    
    public class Foo
    {
        public int Id { get; set; }
        public string FirstName { get; set; }
    }
    

    【讨论】:

    • 如果我运行你的代码,我在 v6.0.0 中得到的 record 的值是一个包含 2 个数组成员(值“1”和“David”)的字符串数组,并且在第二个例如,在 v12.3.2 中,它是一个包含 1 个数组成员(“1,David”)的字符串数组。如果您在两个示例中看到相同的值,我会怀疑这是否是环境问题。
    • 肯定有其他事情发生,因为我得到了两个数组成员(值“1”和“大卫”)。尝试添加csv.Configuration.Delimiter = ",";
    • 成功了!不过,仍然对您的代码为什么不需要这一行感到好奇。也许您评论中的这一行可以添加到答案中,因为 cmets 有时会被忽略。非常感谢!
    • 我会将其添加到答案中。问题是本地化,它一定是 6.0.0 和现在之间变化的一部分。默认分隔符使用CultureInfo.CurrentCulture.TextInfo.ListSeparator。我在美国,所以我的默认 ListSeparator 是逗号。我猜你的可能是;
    • 正确,我的默认 ListSeparator 是;。在原始代码中有一行csv.Configuration.CultureInfo = CultureInfo.CreateSpecificCulture("en-US");,但显然,正如您所提到的,分隔符也必须设置。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2018-06-22
    • 2019-07-15
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多