更新: 这是我的解决方案
我定义了一个表:
CREATE TABLE [dbo].[csvrf_References]
(
[Ident] [int] IDENTITY(1,1) NOT NULL,
[ReferenceID] [uniqueidentifier] NOT NULL DEFAULT (newsequentialid()),
[Type] [nvarchar](255) NOT NULL,
[Location] [nvarchar](1000) NULL,
[Description] [nvarchar](2000) NULL,
[CreatedOn] [datetime] NOT NULL DEFAULT (getdate()),
[LastUpdatedOn] [datetime] NOT NULL DEFAULT (getdate()),
[LastUpdatedUser] [nvarchar](100) NOT NULL DEFAULT (suser_sname()),
CONSTRAINT [PK_References] PRIMARY KEY NONCLUSTERED ([ReferenceID] ASC)
) ON [PRIMARY]
我有一个
DataTable
,其中的列与表格列名和数据类型匹配。 DataTable
中用DBNull.Value
填充了CreatedOn
,LastUpdatedOn
和LastUpdatedUser
。已经生成了ReferenceID
。当我调用以下代码时,会收到下面的错误提示:
代码:
SqlBulkCopy bulkCopy = new SqlBulkCopy(conn, SqlBulkCopyOptions.Default, bulkCopyTran);
bulkCopy.DestinationTableName = table.TableName;
bulkCopy.ColumnMappings.Clear();
foreach (DataColumn col in table.Columns) bulkCopy.ColumnMappings.Add(col.ColumnName, col.ColumnName);
bulkCopy.WriteToServer(table);
错误:
尝试批量复制表csvrf_References时出现错误
System.InvalidOperationException: 列“CreatedOn”不允许DBNull.Value。
at System.Data.SqlClient.SqlBulkCopy.ConvertValue(Object value, _SqlMetaData metadata, Boolean isNull, Boolean& isSqlType, Boolean& coercedToDataFeed)
我已经搜遍了所有的地方,但似乎找不到答案。尽管SqlBulkCopy
类声称支持默认值,但实际上并未如此。我在这里做错了什么?
DBNull.Value
应该在相关字段上有默认约束时转换为Default
,所以它应该可以工作?对于我来说,在使用.NET 4.5和SQL Server 2012时,我无法通过将DBNull.Value传递给具有默认约束的非空字段来使SqlBulkCopy工作。 - Tim LentineSqlBulkCopy
使其工作,并且b)如果您想选择默认值,则根本不能指定标记为“NOT NULL”的字段(这是我在第1部分中提到的)。我在第2部分中提到的将其转换为“DEFAULT”是关于可空字段的,这涵盖了詹姆斯在您的答案评论中提到的“其他表格中我将有包含数据以及nulls的列”的内容。但是,是的,令人困惑的是,SqlBulkCopy
根据字段被声明为“NULL”还是“NOT NULL”而不同地处理DbNull.value
。 - Solomon RutzkyDbNull.Value
在可空字段上使用默认值是完全可以的,那么为什么在非空字段上也不能呢?我唯一能想到的原因是,首先会有一个验证步骤,它会将数据与模式进行比较,但不知道 BulkCopyOptions 值。我怀疑这种行为并不是故意的,要么是开发人员不知道(听起来像个 bug),要么是已知的,但要么“不值得修复”,要么“还没有修复”。无论哪种方式,:(。 - Solomon Rutzky