3

我正在尝试使用 fastmember ( Fastmember NuGet ) 扩展和 sqlbulkcopy 将某个自定义对象列表插入到我的数据库中。但是它给了我以下错误:

An unhandled exception of type 'System.Data.SqlClient.SqlException' occurred in System.Data.dll

Additional information: Cannot insert the value NULL into column 'functionblockId', table '\path...\DBFHX.MDF.dbo.connections'; column does not allow nulls. INSERT fails.

The statement has been terminated.

代码:

private void insertConnection(functionblock functionblock)
{
    using (var bcp = new SqlBulkCopy(db.Database.Connection.ConnectionString))
    {
        foreach (connection item in functionblock.connections)
                {
                    item.functionblockId = 1;
                }
        using (var creader = ObjectReader.Create(functionblock.connections, "step", "transition","steptotrans", "functionblockId"))
                {
                    bcp.DestinationTableName = "connections";
                    bcp.WriteToServer(creader);
                }   
    }
}

使用 Model First,实体框架生成了下表:

CREATE TABLE [dbo].[connections] (
    [Id]              INT            IDENTITY (1, 1) NOT NULL,
    [step]            NVARCHAR (MAX) NOT NULL,
    [transition]      NVARCHAR (MAX) NOT NULL,
    [steptotrans]     BIT            NOT NULL,
    [functionblockId] INT            NOT NULL,
    CONSTRAINT [PK_connections] PRIMARY KEY CLUSTERED ([Id] ASC),
    CONSTRAINT [FK_functionblockconnection] FOREIGN KEY ([functionblockId]) REFERENCES [dbo].[functionblocks] ([Id])
);

该代码适用于另一个表,该表还包含相同的“functionblockId”和相同类型的其他字段(虽然不包含位字段)。

我手动检查了我在 functionblock.connections 列表中的所有值,然后在特定的对象中检查了它的“functionblockId”,它都用一个数字填充。更好的是,正如您在代码中看到的那样,我实际上在批量插入之前确实将其填充为硬编码。

我不知道为什么会出现这个错误,有人知道吗?

4

2 回答 2

8

After manually making a DataTable with test data it still gave me the same error.

I came across this post (codeproject solution), and applied the SqlBulkCopyColumnMapping to my case.

Code example:

using (var bcp = new SqlBulkCopy(fhxm.Database.Connection.ConnectionString))
                                    {
                                    using (var creader = ObjectReader.Create(functionblock.connections, "step", "transition", "steptotrans", "functionblockId"))
                                    {
                                    SqlBulkCopyColumnMapping mapstep = new SqlBulkCopyColumnMapping("step", "step");
                                    SqlBulkCopyColumnMapping maptran = new SqlBulkCopyColumnMapping("transition", "transition");
                                    SqlBulkCopyColumnMapping mapstt = new SqlBulkCopyColumnMapping("steptotrans", "steptotrans");
                                    SqlBulkCopyColumnMapping mapfunc = new SqlBulkCopyColumnMapping("functionblockId", "functionblockId");
                                    bcp.ColumnMappings.Add(mapstep);
                                    bcp.ColumnMappings.Add(maptran);
                                    bcp.ColumnMappings.Add(mapstt);
                                    bcp.ColumnMappings.Add(mapfunc);

                                    bcp.DestinationTableName = "connections";
                                    bcp.WriteToServer(creader);
                                    }   } 
于 2014-10-01T08:35:11.547 回答
0

但是,对这种语法并不十分熟悉:我想知道“项目”对象是否真的在事务中使用。它看起来像 ObjectReader.Create 步骤通过连接,独立于“项目”引用。

尝试减少事务计数以确认正确的行计数到达,因为您可能会踩到迭代器。

另外,也许您可​​以尝试捕获 item.functionblockId 的意外值,作为诊断工具。

于 2014-09-30T19:54:09.133 回答