具有并发队列的sqlbulkcopy

时间:2017-01-13 14:18:46

标签: c# sql-server-2012

我有一个使用类对象定义的并发队列,该对象包含65000条记录,如下所示

ConcurrentQueue<Data> DataQueue = new ConcurrentQueue<Data>();

public class Data
{
    public string Id { get; set; }
    public string T { get; set; }
    public string D { get; set; }
    public string L { get; set; }
    public string I { get; set; }
    public string V { get; set; }
}

我正在使用以下代码插入db

public void InsertIntoDB()
    {

        using (cn = new SqlConnection(connectionString))
        {
            cn.Open();

            Data item;
            while (SpotDataQueue.Count > 0)
            {
                if (DataQueue.TryDequeue(out item))
                {
                    using (SqlCommand cm = cn.CreateCommand())
                    {
                        cm.CommandText = @"INSERT INTO [TableName] ([WId], [L], [I], [V],[JId],[I],[DateTime]) VALUES (@WId, @l, @i, @v, @jid,@i,@dt)";
                        cm.Parameters.AddWithValue("WId", item.Id);
                        cm.Parameters.AddWithValue("@l", item.L);
                        cm.Parameters.AddWithValue("@i", item.I);
                        cm.Parameters.AddWithValue("@v", item.V);
                        cm.Parameters.AddWithValue("@jid", 1);
                        cm.Parameters.AddWithValue("@i", false);
                        cm.Parameters.AddWithValue("@dt", DateTime.Now);
                        cm.ExecuteNonQuery();
                    }
                }
            }
        }
    }

表格结构:

WId         nvarchar(50)    AllowNulls
L           nvarchar(MAX)   AllowNulls
I           nvarchar(MAX)   AllowNulls
V           nvarchar(MAX)   AllowNulls
JId         int             AllowNulls
I           bit             AllowNulls
DateTime    datetime        AllowNulls

如何将Data类型的并发队列转换为DATATABLE或DATAREADER以使SQLBULKCOPY成为可能?

感谢。

1 个答案:

答案 0 :(得分:3)

Here是一种借助反射(更改参数类型)完成工作的方法:

public static DataTable ToDataTable<T>(this IEnumerable<T> items)
{
    var tb = new DataTable(typeof(T).Name);

    PropertyInfo[] props = typeof(T).GetProperties(BindingFlags.Public | BindingFlags.Instance);

    foreach(var prop in props)
    {
        tb.Columns.Add(prop.Name, prop.PropertyType);
    }

    foreach (var item in items)
    {
       var values = new object[props.Length];
        for (var i=0; i<props.Length; i++)
        {
            values[i] = props[i].GetValue(item, null);
        }

        tb.Rows.Add(values);
    }

    return tb;
}

现在,您可以将其与Queue

一起使用
DataTable dataSourceForSqlBulkCopy = DataQueue.ToDataTable();