为什么 DataRow 中的时间戳不是自动生成的?
Why does Timestamp in DataRow is not auto generated?
我正在尝试对数据库进行批量插入,我之前的尝试是使用 dapper 进行批量插入,但这太可怕了,所以我尝试使用 clean ADO.NET
方法
我生成数据表并从项目列表中填充它:
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 是时间戳列,为什么不自动生成?我做错了什么?
编辑
TABLE 防御力:
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]
sql table 中具有时间戳数据类型的列是自动生成的,不要在其中显式插入值,只要在 table 中插入记录,它就会填充当前时间戳
将您的代码更改为以下内容,以提及 LastTimeStamp
是一个 TimeStamp
类型,否则实际上您说的是 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);
}
列 "LastTimeStamp" 是数据表的一部分,因此需要一个值。它是您的 DataTable 的一部分,因为您 select 来自 table
的所有行和列
var cmd = new SqlCommand("SET FMTONLY ON; SELECT * FROM Voucher; SET FMTONLY OFF;", cn);
...
dt.Load(cmd.ExecuteReader());
是否需要在批量插入之前将所有值加载到 DataTable 中?我猜不会。因此,您可以通过避免使用 select 和 dt.Load
来解决问题,而是仅将要批量插入的列添加到 table 中:
table.Columns.Add("VoucherUid", typeof (...));
或者,我认为您仍然可以使用 select,但只能使用 select 您还将插入的列。
我正在尝试对数据库进行批量插入,我之前的尝试是使用 dapper 进行批量插入,但这太可怕了,所以我尝试使用 clean ADO.NET 方法
我生成数据表并从项目列表中填充它:
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 是时间戳列,为什么不自动生成?我做错了什么?
编辑 TABLE 防御力:
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]
sql table 中具有时间戳数据类型的列是自动生成的,不要在其中显式插入值,只要在 table 中插入记录,它就会填充当前时间戳
将您的代码更改为以下内容,以提及 LastTimeStamp
是一个 TimeStamp
类型,否则实际上您说的是 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);
}
列 "LastTimeStamp" 是数据表的一部分,因此需要一个值。它是您的 DataTable 的一部分,因为您 select 来自 table
的所有行和列var cmd = new SqlCommand("SET FMTONLY ON; SELECT * FROM Voucher; SET FMTONLY OFF;", cn);
...
dt.Load(cmd.ExecuteReader());
是否需要在批量插入之前将所有值加载到 DataTable 中?我猜不会。因此,您可以通过避免使用 select 和 dt.Load
来解决问题,而是仅将要批量插入的列添加到 table 中:
table.Columns.Add("VoucherUid", typeof (...));
或者,我认为您仍然可以使用 select,但只能使用 select 您还将插入的列。