C# CsvHelper-使用映射写入SQL数据库

C# CsvHelper-使用映射写入SQL数据库,c#,csvhelper,C#,Csvhelper,到目前为止,CSVHelper.NET库似乎非常棒,但是对于像我这样的伪初学者来说,文档有点缺乏 我需要读取csv文件并将结果写入SQL Server数据库。对于我要写入的表,我需要从CSV列映射到它的列,包括将多个字段连接到一个字段 这是我用来读取csv文件的工具: public static void Main(string[] args) { using (var reader = new StreamReader(@"C:\Users\me\Documents\file.csv"

到目前为止,CSVHelper.NET库似乎非常棒,但是对于像我这样的伪初学者来说,文档有点缺乏

我需要读取csv文件并将结果写入SQL Server数据库。对于我要写入的表,我需要从CSV列映射到它的列,包括将多个字段连接到一个字段

这是我用来读取csv文件的工具:

public static void Main(string[] args)
{
    using (var reader = new StreamReader(@"C:\Users\me\Documents\file.csv"))
    using (var csv = new CsvReader(reader))          
    {
        csv.Configuration.PrepareHeaderForMatch = (string header, int index) =>
            header.Replace(" ", "_").Replace("(", "").Replace(")", "").Replace(".", "");
        var records = csv.GetRecords<EntityCsv>().ToList();
    }
}
我从他那里借用了这个代码块,并在理论上运行该方法作为最后一步

但我知道我在这两者之间遗漏了一步,那就是将字段从csv映射到SQL server字段。我在琢磨如何实施这一步骤

为了简单起见,我在csv文件中有3列,我想将它们映射到SQL表的2列,如下所示:

CsvColumn1 -> SQLtableColumn1
CsvColumn2 + CsvColumn3 -> SQLtableColumn2
我将如何使用CsvReader和C来实现这一点?我已经研究了CSVReader文档中的映射部分,但我在其中看到的一切似乎都是指将列名从输入文件映射到输出文件中的名称。我在Google上的任何地方都看不到任何特别提到获取输入文件并将其行导出到SQL数据库的内容。

我使用SqlBulkCopy和csvhelper将数据转储到SQL server

SqlBulkCopy是一个非常棒的实用工具,它可以从几乎任何可以加载到DataTable实例的数据源向sql server写入数据

var lines = File.ReadAllLines(file);
if (lines.Count() == 0) 
    return;

var tableName = GetTableName(file);
var columns = lines[0].Split(',').ToList();
var table = new DataTable();
sqlBulk.ColumnMappings.Clear();

foreach (var c in columns)
{
    table.Columns.Add(c);
    sqlBulk.ColumnMappings.Add(c, c); 
}

for (int i = 1; i < lines.Count() - 1; i++)
{
    var line = lines[i];
    // Explicitly mark empty values as null for SQL import to work
    var row = line.Split(',')
        .Select(a => string.IsNullOrEmpty(a) ? null : a).ToArray();
    table.Rows.Add(row);
}

sqlBulk.DestinationTableName = tableName;
sqlBulk.WriteToServer(table);
我使用了SqlBulkCopy和csvhelper将数据转储到sql server

SqlBulkCopy是一个非常棒的实用工具,它可以从几乎任何可以加载到DataTable实例的数据源向sql server写入数据

var lines = File.ReadAllLines(file);
if (lines.Count() == 0) 
    return;

var tableName = GetTableName(file);
var columns = lines[0].Split(',').ToList();
var table = new DataTable();
sqlBulk.ColumnMappings.Clear();

foreach (var c in columns)
{
    table.Columns.Add(c);
    sqlBulk.ColumnMappings.Add(c, c); 
}

for (int i = 1; i < lines.Count() - 1; i++)
{
    var line = lines[i];
    // Explicitly mark empty values as null for SQL import to work
    var row = line.Split(',')
        .Select(a => string.IsNullOrEmpty(a) ? null : a).ToArray();
    table.Rows.Add(row);
}

sqlBulk.DestinationTableName = tableName;
sqlBulk.WriteToServer(table);
您可以使用类映射将csv列映射到sql表列,并跳过CSventy类

公共静态无效字符串[]args { 使用var reader=newStreamReader@C:\Users\me\Documents\file.csv 使用var csv=new CsvReaderreader { csv.Configuration.prepareHeadePerformatch=字符串头,int索引=> 收割台.更换,u.更换,.Replace,.Replace; csv.Configuration.RegisterClassMap; var records=csv.GetRecords.ToList; } } 公共类任务实体 { 公共int Id{get;set;} 公共字符串SqlTableColumn1{get;set;} 公共字符串SqlTableColumn2{get;set;} } 公共密封类TaskEntityMap:ClassMap { 公共任务映射 { Mapm=>m.SqlTableColumn1.NameCsvColumn1; Mapm=>m.SqlTableColumn2.ConvertUsingrow=>row.GetFieldCsvColumn2++row.GetFieldCsvColumn3; } } 您可以使用类映射将csv列映射到sql表列,并跳过CSventy类

公共静态无效字符串[]args { 使用var reader=newStreamReader@C:\Users\me\Documents\file.csv 使用var csv=new CsvReaderreader { csv.Configuration.prepareHeadePerformatch=字符串头,int索引=> 收割台.更换,u.更换,.Replace,.Replace; csv.Configuration.RegisterClassMap; var records=csv.GetRecords.ToList; } } 公共类任务实体 { 公共int Id{get;set;} 公共字符串SqlTableColumn1{get;set;} 公共字符串SqlTableColumn2{get;set;} } 公共密封类TaskEntityMap:ClassMap { 公共任务映射 { Mapm=>m.SqlTableColumn1.NameCsvColumn1; Mapm=>m.SqlTableColumn2.ConvertUsingrow=>row.GetFieldCsvColumn2++row.GetFieldCsvColumn3; } }
很高兴再次见到你,大卫。这似乎是我一直在寻找的答案。让我确保它有效,如果有效,我会将此标记为答案,以便您获得赏金。谢谢嗨,戴维,我刚刚遇到了一件我没想到的事情——我敢肯定你的解决方案会起作用,我会奖励你的奖金,不管怎样-快速的问题:让我说我创建两个不同的实体地图,TaskTyTyMaP1和TaskTyTyMaP2;然后,在csv文件中,如果给定行的第一个字段为1,则使用TaskEntityMap1将该行映射到SQL,如果为2,则使用TaskEntityMap2。这两个映射将映射到同一个SQL表,只是映射到不同的字段。当我使用CSVHelper时,在代码中我将在哪里处理该逻辑,因为没有涉及到每个循环?您可能需要循环每个记录,以便检查第一个记录的映射标志。请参阅上的文档,我将进行一次读取,读取标题,再次读取,然后按名称或索引检查标记字段。注册特定的类映射。调用GetRecord来添加该记录,而不是添加每个属性,然后启动whilecsv.Read循环来获取其余的记录。如果你还需要更多,就开始一个新的StackOverflow问题。嗨,大卫,谢谢,这是一个很好的观点,我应该开始一个新的问题。我会的。看来你上面的答案确实符合原意
最后一个问题,很快我会把它作为答案,奖励你奖金。再次感谢!大卫,如果你感兴趣的话:很高兴再次见到你,大卫。这似乎是我一直在寻找的答案。让我确保它有效,如果有效,我会将此标记为答案,以便您获得赏金。谢谢嗨,戴维,我刚刚遇到了一件我没想到的事情——我敢肯定你的解决方案会起作用,我会奖励你的奖金,不管怎样-快速的问题:让我说我创建两个不同的实体地图,TaskTyTyMaP1和TaskTyTyMaP2;然后,在csv文件中,如果给定行的第一个字段为1,则使用TaskEntityMap1将该行映射到SQL,如果为2,则使用TaskEntityMap2。这两个映射将映射到同一个SQL表,只是映射到不同的字段。当我使用CSVHelper时,在代码中我将在哪里处理该逻辑,因为没有涉及到每个循环?您可能需要循环每个记录,以便检查第一个记录的映射标志。请参阅上的文档,我将进行一次读取,读取标题,再次读取,然后按名称或索引检查标记字段。注册特定的类映射。调用GetRecord来添加该记录,而不是添加每个属性,然后启动whilecsv.Read循环来获取其余的记录。如果你还需要更多,就开始一个新的StackOverflow问题。嗨,大卫,谢谢,这是一个很好的观点,我应该开始一个新的问题。我会的。看起来你上面的答案确实满足了原来的问题,所以很快我会把它标记为答案来奖励你。再次感谢!大卫,如果你感兴趣的话: