2016-01-06 7 views
0

Я пытаюсь сделать массовую вставку в БД, моя предыдущая попытка была использовать щеголеватый для массовой вставки, но это было ужасно, поэтому я попытался с чистой ADO.NET подходаПочему временная метка в DataRow не сгенерирована автоматически?

Я Сформировать DataTable и заполнить его из списка пунктов:

using (SqlConnection cn = new SqlConnection(VoucherConnectionManager.connectionString)) 
       { 
        cn.Open(); 
        var cmd = new SqlCommand("SET FMTONLY ON; SELECT * FROM Voucher; SET FMTONLY OFF;", cn); 
        var dt = new DataTable(); 

        dt.Load(cmd.ExecuteReader()); 

        foreach (var itm in voucherList) 
        { 
         DataRow row = dt.NewRow(); 
         row["VoucherUid"] = itm.Uid; 
         row["ClientUid"] = itm.ClientUid; 
         row["BatchUid"] = itm.BatchUid; 
         row["CardNo"] = itm.CardNo; 
         row["Origin"] = itm.Origin; 
         row["VoucherCreateDate"] = itm.VoucherCreateDate; 
         row["State"] = itm.State; 
         //row["LastTimeStamp"] = DateTime.Now; 

         dt.Rows.Add(row); 
        } 
        using (SqlBulkCopy bulkCopy = new SqlBulkCopy(cn)) 
        { 
         bulkCopy.DestinationTableName = "dbo.Voucher"; 
         bulkCopy.WriteToServer(dt); 
        } 
        cn.Dispose(); 
       } 

проблема здесь состоит в том, что я получаю следующее сообщение об ошибке:

An unhandled exception of type 'System.Data.NoNullAllowedException' occurred in MasterRepositorys.dll 

Additional information: Column 'LastTimeStamp' does not allow nulls. 

LastTimeStamp - это временная колонка, почему она не генерируется автоматически? Что я сделал не так?

EDIT ТАБЛИЦА DEF:

CREATE TABLE [dbo].[Voucher](
    [VoucherUid] [uniqueidentifier] NOT NULL, 
    [ClientUid] [uniqueidentifier] NOT NULL, 
    [BatchUid] [uniqueidentifier] NOT NULL, 
    [CardNo] [nvarchar](13) NOT NULL, 
    [CycleUid] [uniqueidentifier] NULL, 
    [CycleCreateDate] [datetime] NULL, 
    [VoucherCreateDate] [datetime] NOT NULL, 
    [LastTimeStamp] [timestamp] NOT NULL, 
    [Type] [int] NULL, 
    [Origin] [int] NOT NULL, 
    [OrderRef] [nvarchar](36) NULL, 
    [State] [int] NOT NULL, 
CONSTRAINT [PK_Voucher] PRIMARY KEY CLUSTERED 
(
    [VoucherUid] ASC 
)WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON) ON [PRIMARY] 
) ON [PRIMARY] 
+0

Действительно ли это временная метка (aka rowversion), а не только дата? Если это datetime, вам нужно будет иметь значение по умолчанию для него или указать его в предложении insert –

+1

Можете ли вы показать фактическое определение таблицы как оператор 'CREATE TABLE'? Обратите внимание, что «timestamp» в SQL Server имеет определенное значение, которое не связано со временем. –

+0

добавлено определение таблицы – Timsen

ответ

1

Столбец «LastTimeStamp» является частью вашего DataTable, и поэтому ожидается значение. Она является частью вашего DataTable, потому что вы выбираете все строки и столбцы из таблицы

var cmd = new SqlCommand("SET FMTONLY ON; SELECT * FROM Voucher; SET FMTONLY OFF;", cn); 
... 
dt.Load(cmd.ExecuteReader()); 

вам необходимо загрузить все значения в DataTable до сыпучей вставки делать? Наверное, нет. Таким образом, вы можете решить эту проблему, избегая выбор и dt.Load и вместо того, чтобы добавить только те столбцы, которые вы хотите массовую вставку в таблицу, как, что:

table.Columns.Add("VoucherUid", typeof (...)); 

Кроме того, я думаю, вы все еще можете использовать выбор, но только выбрать столбцы вы также будете вставлять.

+0

в итоге выбраны только столбцы нумерации – Timsen

0

Колонка в SQL таблицу с отметкой времени тип данных автогенерируемая, не вставить значения в нем явно и всякий раз, когда запись вставляется в таблицу он будет заполняться с током timestamp

+0

Где я вставляю отметки времени в таблице? – Timsen

0

Измените свой код на нижеследующий, чтобы упомянуть, что LastTimeStamp - это TimeStamp типа else, по существу, вы говорите LastTimeStamp is null и поэтому получаете ошибку.

  foreach (var itm in voucherList) 
      { 
       DataRow row = dt.NewRow(); 
       row["VoucherUid"] = itm.Uid; 
       row["ClientUid"] = itm.ClientUid; 
       row["BatchUid"] = itm.BatchUid; 
       row["CardNo"] = itm.CardNo; 
       row["Origin"] = itm.Origin; 
       row["VoucherCreateDate"] = itm.VoucherCreateDate; 
       row["State"] = itm.State; 
       row["LastTimeStamp"] = SqlDbType.Timestamp; //Here 

       dt.Rows.Add(row); 
      }