【问题标题】:Why does Timestamp in DataRow is not auto generated?为什么 DataRow 中的时间戳不是自动生成的?
【发布时间】:2016-01-06 07:59:41
【问题描述】:

我正在尝试对 DB 进行批量插入,我之前的尝试是使用 dapper 进行批量插入,但这太可怕了,所以我尝试使用干净的 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 是一个时间戳列,为什么不自动生成?我做错了什么?

编辑 表定义:

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]

【问题讨论】:

  • 它真的是一个时间戳(又名行版本)字段而不仅仅是日期时间吗?如果是日期时间,您需要为其设置一个默认值,或者在您的插入子句中提供它
  • 您能否将实际的表定义显示为CREATE TABLE 语句?请注意,SQL Server 中的timestamp 具有特定含义,与时间无关。
  • 添加表定义
  • 因为错误提示您不能在该列中插入空值。查看您的表格和要求,您可能需要在列中允许空值。
  • 如果您想存储日期/时间值,您选择了错误的类型。见rowversion (a.k.a. timestamp)

标签: c# sql-server datatable datarow datacolumn


【解决方案1】:

“LastTimeStamp”列是 DataTable 的一部分,因此需要一个值。它是 DataTable 的一部分,因为您从表中选择所有行和列

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

是否需要在批量插入之前将所有值加载到 DataTable 中?我猜不会。因此,您可以通过避免 select 和 dt.Load 来解决问题,而是只将要批量插入的列添加到表中,如下所示:

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

或者,我认为您仍然可以使用选择,但只选择您还将插入的列。

【讨论】:

  • 只选择了必要的列
【解决方案2】:

带有时间戳数据类型的sql表中的列是自动生成的,不要在其中显式插入值,并且每当将记录插入表中时,它将用当前时间戳填充

【讨论】:

  • 我在哪里插入时间戳?
【解决方案3】:

将您的代码更改为以下,以提及 LastTimeStampTimeStamp 类型,否则本质上您是在说 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);
            }

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2014-01-27
    • 2014-07-02
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-12-18
    • 1970-01-01
    相关资源
    最近更新 更多