Csvhelper Ignore 仅删除 header 列名称,但不删除实际数据

Csvhelper Ingore is removing only header column name but no the actual data

我在我的数据库中加载了一个 csv 文件,其中 DbId 列不在文件中。

我想把它导出回原来的格式。

我的 csvhelper 映射在 MyCsvClassMap(m => m.DbId).Ignore();

Header 很好,但输出数据仍然显示 DbId 列的值: https://dotnetfiddle.net/XP2Vvq

using CsvHelper.Configuration;
using System;
using System.IO;

namespace Test
{
    class Program
    {
        static void Main(string[] args)
        {
            var record = new { DbId = 1, Data1 = "aaa", Data2 = "bbb" };

            using (var sw = new StreamWriter(@"c:/temp/testt.csv"))
            {
                using (var csvWriter = new CsvHelper.CsvWriter(sw))
                {
                    csvWriter.Configuration.RegisterClassMap<MyCsvClassMap>();
                    csvWriter.WriteHeader<MyCsvClass>();
                    csvWriter.NextRecord();
                    csvWriter.WriteRecord(record);
                }
            }
        }
    }

    public class MyCsvClassMap : ClassMap<MyCsvClass>
    {
        public MyCsvClassMap()
        {
            AutoMap();
            Map(m => m.DbId).Ignore();
        }
    }

    public class MyCsvClass
    {
        public int DbId { get; set; }
        public string Data1 { get; set; }
        public string Data2 { get; set; }      
    }   
}

输出为

Data1, Data2
1, "aaa", "bbb"

我期待的时候

Data1, Data2
"aaa", "bbb"

我认为 ClassMap 配置不正确。不知道为什么您的示例可以正常工作,因为它不应该编译。

你能不能修改下面这行代码来注册ClassMapMyCsvClassMap而不是MyCsvClass):

csvWriter.Configuration.RegisterClassMap<MyCsvClassMap>();

您的示例的其余部分工作正常。

尝试以下控制台应用程序:

class Program
{
    static void Main(string[] args)
    {
        var allRecords = new List<MyCsvClass>()
        {
            new MyCsvClass { DbId = "1", Data1 = "data1", Data2 = "data2"}
        };
        using (var sw = new StreamWriter("C:\temp\test.csv"))
        {
            using (var csvWriter = new CsvHelper.CsvWriter(sw))
            {
                csvWriter.Configuration.RegisterClassMap<MyCsvClassMap>();
                csvWriter.WriteHeader<MyCsvClass>();
                csvWriter.NextRecord();
                csvWriter.WriteRecords(allRecords);
            }
        }
    }

    public class MyCsvClassMap : ClassMap<MyCsvClass>
    {
        public MyCsvClassMap()
        {
            AutoMap();
            Map(m => m.DbId).Ignore();
        }
    }

    public class MyCsvClass
    {
        public string DbId { get; set; }
        public string Data1 { get; set; }
        public string Data2 { get; set; }
    }
}

如果这有效,则可能是其他一些代码导致了此行为。

您的代码的问题是您创建了一个匿名类型的实例

var record = new { DbId = 1, Data1 = "aaa", Data2 = "bbb" };

而不是

var record = new MyCsvClass { DbId = 1, Data1 = "aaa", Data2 = "bbb" };

header 很好,因为您将正确的 class 传递给泛型方法的类型参数。

csvWriter.WriteHeader<MyCsvClass>();

编辑

要将数据库实体导出为 CSV,您不需要任何中间体 class。您可以将实体直接写入 CSV,ClassMap<T> 可帮助您控制哪些值以及如何序列化为 CSV。如果您的实体 class 是 MyDbEntity,那么只需注册自定义映射 ClassMap<MyDbEntity>,您 auto-map 所有字段都将忽略某些字段,就像您在 MyCsvClassMap 中所做的那样。