【问题标题】:When using the .NET CsvHelper library, is there an easy way to put the base class fields first?使用 .NET CsvHelper 库时,是否有一种简单的方法可以将基类字段放在首位?
【发布时间】:2020-04-20 21:14:55
【问题描述】:

我正在序列化许多不同的 POCO 对象,它们都继承自一个公共抽象类 - 例如AbstractBaseClass。在序列化这个类时,我使用WriteRecords<dynamic> 方法,它接受几乎任何东西,并且表面上使用反射将属性写入 CSV。

我遇到的问题是,我希望基类字段在文件中排在第一位。看起来 CsvHelper 的默认行为是将它们放在最后。

我可以看到有一种方法可以实例化一个映射器来索引字段,但是对于从AbstractBaseClass 继承的许多类型中的每一个,都很难做到这一点。我只想配置一次,让它适用于从所述类继承的任何东西。更好的是,可以使用某种切换方式来更改 CsvHelper 在继承树中搜索字段的方式。

【问题讨论】:

    标签: c# csvhelper


    【解决方案1】:

    您可以使用通用方法创建您的ClassMap,并将基类属性的索引设置为负数,以便它们位于继承类的属性之前。

    public class Program
    {
        public static void Main(string[] args)
        {        
            var records = new List<Foo> {
                new Foo{Id = 1, FirstName = "FirstName1", FooProperty = "Foo1", LastName = "LastName1"},
                new Foo{Id = 2, FirstName = "FirstName2", FooProperty = "Foo2", LastName = "LastName2"}
            };
    
            var config = GetFooBaseConfiguration(records);
    
            using (var csv = new CsvWriter(Console.Out, config))
            {
                csv.WriteRecords(records);
            }
    
            Console.ReadKey();
        }
    
        public static CsvConfiguration GetFooBaseConfiguration<T>(IEnumerable<T> records) where T : FooBase
        {
            var config = new CsvConfiguration(CultureInfo.InvariantCulture);
    
            var classMap = new DefaultClassMap<T>();
    
            classMap.AutoMap(CultureInfo.InvariantCulture);
            classMap.Map(m => m.FirstName).Index(-1,-2);
            classMap.Map(m => m.LastName).Index(-2,-3);
    
            config.RegisterClassMap(classMap);
    
            return config;
        }
    }
    
    public abstract class FooBase
    {
        public string FirstName { get; set; }
        public string LastName { get; set; }
    }
    
    public class Foo : FooBase
    {
        public int Id { get; set; }
        public string FooProperty { get; set; }
    }
    

    【讨论】:

    • 我得到了一个非常奇怪的结果,我都尝试了你上面给出的例子,以及在基类字段上使用 Index(-3) 等属性。具体来说,我的基础类分别包含字段IdReportIdPortfolioId-3-2-1,在输出中我看到列标签:Id1|Id2|Id3|ReportId1|ReportId2|PortfolioId1|(derived class fields)。不仅如此,派生类字段是空白的,它们的值已移动到基类列 - 它产生了一个格式错误的文件。
    • 看起来它正试图将它们视为 IEnumerable 属性。我可以通过添加一个比起始索引至少负数一个的结束索引来修复它。
    猜你喜欢
    • 1970-01-01
    • 2012-06-29
    • 1970-01-01
    • 2016-01-19
    • 2011-12-26
    • 2011-08-26
    • 1970-01-01
    • 2013-07-29
    相关资源
    最近更新 更多