使用FileHelpers时,如何在SQL Server中将CSV空字符串作为NULL加载?

时间:2019-03-04 14:47:33

标签: c# ado.net filehelpers

我正在使用FileHelpers读取CSV,目的是加载SQL Server表。

CSV看起来像这样:

ID, SOMESTRING
"10","Blah blah"
"11",""
"12","More blah blah"

我的记录映射类如下所示:

[IgnoreFirst, DelimitedRecord(",")]
class Mytable
{
    [FieldQuoted]
    public ulong Id;

    [FieldQuoted]
    [FieldNullValue(typeof(string), null)]
    public string SomeString;
}

最后,要批量复制到数据库的代码是:

  SqlBulkCopy bc = new SqlBulkCopy(mySqlConnection);
  bc.DestinationTableName = "dbo.MYTABLE";
  bc.WriteToServer(new FileHelperEngine<Mytable>().ReadFile(baseDir + "\\" + "MYTABLE.CSV").ToDataTable<Mytable>());

最初,我没有包括FieldNullValue属性,但是是否包含它似乎并不重要。在这两种情况下,第11行在SQL Server中均作为空字符串导入。我希望它为NULL。能做到吗?

3 个答案:

答案 0 :(得分:1)

如果您打算使用CsvHelper。是的,可以做到。使用Microsoft SQL Server Management Studio 2014时,我能够测试您的方案并能够验证属性SOMESTRING = NULL。 在我的示例中,使用CsvHelper将CSV文件转换为DataTable,然后将任何空字段转换为DBNull.Value。 使用数据库存储过程和用户​​定义的表类型将修改后的数据表插入数据库 最后,从数据库->数据表中读取并查看DataGridView中的记录。 您会注意到空字段为NULL。

创建类型

CREATE TYPE [dbo].[MyProductTableType] AS TABLE(
    [ID] [nvarchar](5) NOT NULL,
    [SOMETHING] [nvarchar](128) NULL
)

创建过程:

CREATE PROCEDURE [dbo].[InsertTable]
    @myTableType MyProductTableType readonly
AS
BEGIN
    insert into [dbo].PRODUCTS select * from @myTableType 
END
在Windows.Forms上使用DataGridView和命令按钮时

C#代码

using System;
using System.Data;
using System.Linq;
using System.Windows.Forms;
using System.Data.SqlClient;
using CsvHelper;

using System.IO;

namespace Stack_Test
{
public partial class Form1 : Form
{
    public Form1()
    {
        InitializeComponent();
    }

    private void button1_Click(object sender, EventArgs e)
    {
        var path = @"C:\Temp\MYTABLE.csv";
        DataTable dt = readCSV(path);

        foreach(DataRow row in dt.Rows)
        {                
            foreach(DataColumn col in dt.Columns)
            {
                if (row.Field<String>(col) == String.Empty)
                {
                    row.SetField(col, DBNull.Value); //row.SetField(col, "NULL"); // Or set the value to any string value of your choice
                }
            }
        }            
        SqlConnection conn = new SqlConnection("Your SQL Connection String");            
        using (var command = new SqlCommand("InsertTable", conn) { CommandType = CommandType.StoredProcedure })
        {
            command.Parameters.Add(new SqlParameter("@myTableType", dt));
            command.Connection.Open();
            command.ExecuteNonQuery();
            command.Dispose();
            dt.Clear();                                                    
        }

        using(var command = new SqlCommand("Select * from PRODUCTS", conn) { CommandType = CommandType.Text})
        {                
            SqlDataReader rdr = command.ExecuteReader();              
            dt.Load(rdr);
            dataGridView1.DataBindings.Clear();
            dataGridView1.DataSource = dt;
            dataGridView1.Refresh();                
            dt.Dispose();
            command.Dispose();
            conn.Close();
            conn.Dispose();
        }            
    } // End button1_Click

使用CsvHelper

public DataTable readCSV(string filePath)
{
    var dt = new DataTable();
    var csv = new CsvReader(new StreamReader(filePath));
    // Creating the columns
    typeof(Product).GetProperties().Select(p => p.Name).ToList().ForEach(x => dt.Columns.Add(x));

    // Adding the rows
    csv.GetRecords<Product>().ToList().ForEach(line => dt.Rows.Add(line.ID, line.SOMETHING));
    return dt;
} // End readCSV : DataTable

一个类对象

public class Product
{
    public string ID { get; set; }
    public string SOMETHING { get; set; }
} // End class Product

SQL Server - DB Result Snapshot

答案 1 :(得分:1)

使用FileHelpers,空字符串将被解析为String.Empty,但是您可以使用自定义转换器覆盖它:

public class EmptyStringConverter : ConverterBase
{
    public override object StringToField(string sourceString)
    {
        if (String.IsNullOrWhiteSpace(sourceString))
            return null;
        return sourceString;
    }
}

然后您像这样定义记录类属性

[FieldConverter(typeof(EmptyStringConverter))]
public string SomeString;

如果与SomeString对应的字符串为空或空白,则将其转换为null。

答案 2 :(得分:0)

我不熟悉您使用的FileHelper软件包,但问题是第11行的值为""而不是null

也许您可以像这样扩展SomeString属性定义

private string _SomeString;

[FieldQuoted]
[FieldNullValue(typeof(string), null)]
public string SomeString { get {return _SomeString;} 
                           set {if (value == null || value.length == 0)    
                                    _SomeString = null;
                                else
                                    _SomeString = value;} }