2014-09-30 4 views
3

Я пытаюсь Bulkinsert создать определенный список пользовательских объектов в моей базе данных, используя расширение fastmember (Fastmember NuGet) и sqlbulkcopy. Однако это дает мне следующую ошибку:SqlBulkCopy Невозможно вставить значение NULL в столбец

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); 
       } 
    } 
} 

Использование модели Во-первых, Entity Framework генерируется в следующей таблице:

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» и тот же самый вид других полей (но не содержит битового поля).

Я вручную проверил все мои значения в списке функцийblock.connections, а затем в конкретном объекте его «functionblockId», он был заполнен номером. Еще лучше, как вы видите в коде, я на самом деле заполняю его жестко запрограммированным, прежде чем я начну его встраивать.

У меня нет подсказки, почему эта ошибка возникает, есть ли у кого-нибудь идеи?

ответ

6

После ручной обработки DataTable с тестовыми данными он все равно дал мне ту же ошибку.

Я наткнулся на это сообщение (codeproject solution) и применил SqlBulkCopyColumnMapping к моему делу.

Пример кода:

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); 
            } } 
+0

Вы должны пропустить столбец идентификаторов с помощью сопоставления столбцов. У вашей другой таблицы нет столбца идентификации? –

+0

У него есть столбец идентификатора, позже я выяснил, выполняю ли я это: ObjectReader.Create (functionblock.connections, «Id», «step», «transition», «steptotrans», «functionblockId»)), он вставляет также без отображение столбцов. – usselite

0

Не очень хорошо знакомы с этим синтаксисом: Интересно, действительно ли объект «item» используется в транзакции. Похоже на ObjectReader.Create шаги через соединения, независимые ссылку 'item'.

Попробуйте уменьшить количество транзакций, чтобы подтвердить правильный подсчет строк, , потому что вы можете наступить на итератор.

также, возможно, вы можете попытаться поймать ловушку для неожиданных значений item.functionblockId, в качестве диагностического инструмента.