使用BulkCopy

时间:2017-12-02 18:40:59

标签: c# sql-server datatable sqlbulkcopy

我试图将我使用记录类动态创建的DataTable对象插入到SQL Server表中。

我面临的问题是其中一个DataTable字段的记录长度超过30000个字符。我正在使用VS2015和SQL Server 2008 R2。

以下是我用于在SQL Server和DataTable对象中创建表的代码(我使用FileHelpers库创建DataTable对象)。< / p>

这是记录类

class MainPartsRecord
{
    [FieldTrim(TrimMode.Both)]
    [FieldQuoted('"', QuoteMode.OptionalForBoth)]
    public int SKU;
    [FieldTrim(TrimMode.Both)]
    [FieldQuoted('"', QuoteMode.OptionalForBoth)]
    public string MANUFACTURER;
    [FieldTrim(TrimMode.Both)]
    [FieldQuoted('"', QuoteMode.OptionalForBoth)]
    public string MODEL;
    [FieldTrim(TrimMode.Both)]
    [FieldQuoted('"', QuoteMode.OptionalForBoth)]
    public string NAME;
    [FieldTrim(TrimMode.Both)]
    [FieldQuoted('"', QuoteMode.OptionalForBoth)]
    public string IMAGE;
    [FieldTrim(TrimMode.Both)]
    [FieldQuoted('"', QuoteMode.OptionalForBoth)]
    public string DESCRIPTION;
    [FieldTrim(TrimMode.Both)]        
    [FieldQuoted('"', QuoteMode.OptionalForBoth)]
    public string UPC;
    [FieldTrim(TrimMode.Both)]
    [FieldQuoted('"', QuoteMode.OptionalForBoth)]
    public int STATUS;
    [FieldTrim(TrimMode.Both)]
    [FieldQuoted('"', QuoteMode.OptionalForBoth)]
    public string META_KEYWORD;
    [FieldTrim(TrimMode.Both)]
    [FieldQuoted('"', QuoteMode.OptionalForBoth)]
    public string PRODUCT_TAGS;
    [FieldTrim(TrimMode.Both)]
    [FieldQuoted('"', QuoteMode.OptionalForRead, MultilineMode.AllowForRead)]
    [FieldConverter(ConverterKind.Date, "yyyy-MM-dd")]
    public DateTime DATA_AVAILABLE;
}

正如您所看到的,我在字段中使用属性,以便可以在运行时正确解析它们。

我正在尝试以下代码

var engine = new FileHelperEngine<MainPartsRecord>();
engine.Options.IgnoreFirstLines = 1;
engine.Options.IgnoreEmptyLines = true;

DataTable dt;

using (dt = engine.ReadFile(item).ToDataTable())
{
    WriteTableToDb(dt);
}

ReadFile方法从磁盘读取.CSV文件并将其转换为DataTable对象。在那之后,我尝试使用以下代码将其发送到SQL Server:

private void WriteTableToDb(DataTable dt)
{                                   
    CheckAndCreateTableToDb();

    var i = 0;

    var bulkCopy = new SqlBulkCopy(Conn.ConnString)
    {
        DestinationTableName = GetTableName(FileName)                                
    };

    foreach (var Column in dt.Columns)
    {
        bulkCopy.ColumnMappings.Add(Column.ToString(), i);
        i++;
    }            

    bulkCopy.WriteToServer(dt);
    bulkCopy.Close();            
}

该表已存在于SQL Server数据库中,并且列具有足够的空间

Data table in SQL Server, columns and sizes

真正的问题是DESCRIPTION列在nvarchar(MAX)对象将BulkCopy发送到SQL Server时使用DataTable,而我收到以下错误:

  

System.InvalidOperationException未处理
  的HResult = -2146233079
  Message =数据源中String类型的给定值无法转换为指定目标列的类型nvarchar   Source = System.Data

     

堆栈跟踪:

     

at System.Data.SqlClient.SqlBulkCopy.ConvertValue(Object value,_SqlMetaData metadata,Boolean isNull,Boolean&amp; isSqlType,Boolean&amp; coercedToDataFeed)
  在System.Data.SqlClient.SqlBulkCopy.ReadWriteColumnValueAsync(Int32 col)
  在System.Data.SqlClient.SqlBulkCopy.CopyColumnsAsync(Int32 col,TaskCompletionSource 1 source)
at System.Data.SqlClient.SqlBulkCopy.CopyRowsAsync(Int32 rowsSoFar, Int32 totalRows, CancellationToken cts, TaskCompletionSource
1来源)
  在System.Data.SqlClient.SqlBulkCopy.CopyBatchesAsyncContinued(BulkCopySimpleResultSet internalResults,String updateBulkCommandText,CancellationToken cts,TaskCompletionSource 1 source) at System.Data.SqlClient.SqlBulkCopy.CopyBatchesAsync(BulkCopySimpleResultSet internalResults, String updateBulkCommandText, CancellationToken cts, TaskCompletionSource 1 source)                          在System.Data.SqlClient.SqlBulkCopy.WriteToServerInternalRestContinuedAsync(BulkCopySimpleResultSet internalResults,CancellationToken cts,TaskCompletionSource 1 source) at System.Data.SqlClient.SqlBulkCopy.WriteToServerInternalRestAsync(CancellationToken cts, TaskCompletionSource 1 source)                          在System.Data.SqlClient.SqlBulkCopy.WriteToServerInternalAsync(CancellationToken ctoken)                          在System.Data.SqlClient.SqlBulkCopy.WriteRowSourceToServerAsync(Int32 columnCount,CancellationToken ctoken)                          在System.Data.SqlClient.SqlBulkCopy.WriteToServer(DataTable表,DataRowState rowState)                          在C:\ PROJECTS \ AutoCon \ TecDocLib \ TecDocMain.cs中的TecDocLib.TecDocMain.WriteTableToDb(DataTable dt):第127行                          在C:\ PROJECTS \ AutoCon \ TecDocLib \ TecDocMain.cs中的TecDocLib.TecDocMain.InsertRecordsToDb(String filename):第77行                          at SOLID_Engine_v4.PartsForms.TecDoc.startImportBtn_Click(Object sender,EventArgs e)在C:\ PROJECTS \ AutoCon \ PartsForms \ TecDoc.cs:第129行                          在System.Windows.Forms.Control.OnClick(EventArgs e)                          在System.Windows.Forms.Control.WmMouseUp(消息&amp; m,MouseButtons按钮,Int32点击)                          在System.Windows.Forms.Control.WndProc(消息&amp; m)                          在System.Windows.Forms.NativeWindow.DebuggableCallback(IntPtr hWnd,Int32 msg,IntPtr wparam,IntPtr lparam)                          在System.Windows.Forms.UnsafeNativeMethods.DispatchMessageW(MSG&amp; msg)                          在System.Windows.Forms.Application.ComponentManager.System.Windows.Forms.UnsafeNativeMethods.IMsoComponentManager.FPushMessageLoop(IntPtr dwComponentID,Int32 reason,Int32 pvLoopData)                          在System.Windows.Forms.Application.ThreadContext.RunMessageLoopInner(Int32 reason,ApplicationContext context)                          在System.Windows.Forms.Application.ThreadContext.RunMessageLoop(Int32 reason,ApplicationContext context)                          在C:\ PROJECTS \ AutoCon \ Program.cs中的SOLID_Engine_v4.Program.Main():第19行                          在System.AppDomain._nExecuteAssembly(RuntimeAssembly程序集,String [] args)                          在System.AppDomain.ExecuteAssembly(String assemblyFile,Evidence assemblySecurity,String [] args)                          在Microsoft.VisualStudio.HostingProcess.HostProc.RunUsersAssembly()                          at System.Threading.ExecutionContext.RunInternal(ExecutionContext executionContext,ContextCallback callback,Object state,Boolean preserveSyncCtx)                          at System.Threading.ExecutionContext.Run(ExecutionContext executionContext,ContextCallback callback,Object state,Boolean preserveSyncCtx)                          在System.Threading.ExecutionContext.Run(ExecutionContext executionContext,ContextCallback回调,对象状态)                          在System.Threading.ThreadHelper.ThreadStart()                     的InnerException:                          的HResult = -2146233079                          Message =字符串或二进制数据将被截断。                          来源= System.Data                          堆栈跟踪:                               at System.Data.SqlClient.SqlBulkCopy.ConvertValue(Object value,_SqlMetaData metadata,Boolean isNull,Boolean&amp; isSqlType,Boolean&amp; coercedToDataFeed)                          InnerException:

我陷入了死胡同。你以前遇到过这样的事吗?

如果您需要有关此问题的任何详细信息,请与我们联系。

提前谢谢你。

0 个答案:

没有答案