【问题标题】:C# DataGridView with Identity Column带有标识列的 C# DataGridView
【发布时间】:2013-06-20 13:33:35
【问题描述】:

我使用 Visual Studio 2010、语言 C# 和 SQL Server Express Edition 作为后端。有一种带有 DataGridView 控件的表单,我使用设计器手动设置列,然后在运行时设置数据源。

connectionString = ConfigurationManager.AppSettings["connectionString"];
sqlConnection = new SqlConnection(connectionString);
sqlConnection.Open();
String sqlSelectDet = "Select OrdDetID, OrderID, ProductID, UnitPrice, Quantity from OrderDetails"; 

//===============================================================================
//--- Set up the INSERT Command OrderDetails
//===============================================================================

sDetInsProcName = "prInsert_OrderDetail";
insertcommandDet = new SqlCommand(sDetInsProcName, sqlConnection);
insertcommandDet.CommandType = CommandType.StoredProcedure;

insertcommandDet.Parameters.Add("@nNewDetID", SqlDbType.Int, 4, "OrdDetID");
insertcommandDet.Parameters.Add("@nOrderID", SqlDbType.Int, 4, "OrderID");
insertcommandDet.Parameters.Add("@nProductID", SqlDbType.Int, 4, "ProductID");
insertcommandDet.Parameters.Add("@mUnitPrice", SqlDbType.Money, 8, "UnitPrice");
insertcommandDet.Parameters.Add("@nQuantity", SqlDbType.SmallInt, 2, "Quantity");

sqlDataDet.InsertCommand = insertcommandDet;

正如代码中提到的,我正在使用存储过程prInsert_OrderDetailOrdDetID 是一种 LineItem 编号,是数据库中的自增字段。

为了设置 DataGridView,我使用以下方法:

dtDet = new DataTable();
dtDet.Clear(); 
sqlDataDet.FillSchema(dtDet, SchemaType.Source);

ds = new DataSet();
ds.Tables.Add(dtDet);

ds.Tables[1].Columns["OrdDetID"].AutoIncrement = true;
ds.Tables[1].Columns["OrdDetID"].AutoIncrementSeed = -1;
ds.Tables[1].Columns["OrdDetID"].AutoIncrementStep = -1;

bsDet = new BindingSource();
bsDet.DataSource = ds;
bsDet.DataMember = "OrderDetails"; 

// Name of DataGridView Control is dgInvDet
dgInvDet.AutoGenerateColumns = false;
dgInvDet.DataSource = bsDet;
dgInvDet.Columns["OrdDetID"].DataPropertyName = "OrdDetID";
dgInvDet.Columns["OrderID"].DataPropertyName = "OrderID";
dgInvDet.Columns["ProductID"].DataPropertyName = "ProductID";
dgInvDet.Columns["UnitPrice"].DataPropertyName = "UnitPrice";
dgInvDet.Columns["Quantity"].DataPropertyName = "Quantity";

在保存按钮单击事件中,使用以下代码将数据从 DataGridView 保存到数据库:

sqlDataDet.Update(ds.Tables[0]);

SQL Server 中的存储过程是这样的:

ALTER  PROCEDURE [dbo].[prInsert_OrderDetail]
@nOrderID INT, 
@nProductID INT, 
@mUnitPrice MONEY, 
@nQuantity SMALLINT,
@nNewDetID INT OUTPUT
AS 
INSERT INTO [OrderDetails] (OrderID, ProductID, UnitPrice, Quantity)
VALUES (@nOrderID, @nProductID, @mUnitPrice, @nQuantity)

    SET @nNewDetID = SCOPE_IDENTITY()

数据已正确保存在数据库中,我的问题是如何获取OrdDetID 实际标识值,将记录插入数据库后,dataGridView 不会在 DataGridView 中显示实际值。因为由于列的设置,我得到的是-1、-2、-3等等。

有什么想法/建议吗?

谢谢

艾哈迈德

【问题讨论】:

    标签: c# datagridview sql-server-express


    【解决方案1】:

    这个参数

    insertcommandDet.Parameters.Add("@nNewDetID", SqlDbType.Int, 4, "OrdDetID");
    

    需要指定为ParameterDirection.Output,即类似于以下代码行:

    SqlParameter pID = new SqlParameter("nNewDetID", DBType.Int32, 4); pID.Direction = ParameterDirection.Output; insertcommandDet.Parameters.Add(pID); //** 这里的其他代码... insertcommandDet.ExecuteScalar();

    执行命令后,通过

    提取值
    int id = Convert.ToInt32(cmd.Parameters["nNewDetID"].Value.ToString());
    

    您应该能够在控制台应用程序中对此进行测试,以帮助您继续...

    // 设置连接 SqlConnection sqlConnection = new SqlConnection("[你的连接字符串]"); // 打开连接 sqlConnection.Open(); // 指定有输出参数的存储过程,即“NewId” SqlCommand insertcommandDet = new SqlCommand("[dbo].[TestingSP]", sqlConnection); // 告诉命令它是一个存储过程 insertcommandDet.CommandType = CommandType.StoredProcedure; // 添加具有名称的参数 insertcommandDet.Parameters.AddWithValue("Name","Test Name"); // 这个参数后面会包含新的id SqlParameter pID = new SqlParameter("NewId", SqlDbType.Int, 4); pID.Direction = ParameterDirection.Output; // 将参数添加到命令中 insertcommandDet.Parameters.Add(pID); // 使用 ExecuteScalar() 执行命令 insertcommandDet.ExecuteScalar(); // 获取使用 ExecuteScalar 提取的参数值 int id = Convert.ToInt32(insertcommandDet.Parameters["NewId"].Value.ToString());

    我使用的过程如下

    创建过程 [dbo].[TestingSP]( @Name varchar(50) , @NewId INT 输出) 作为 插入 [测试] 选择@名称 SET @NewId = SCOPE_IDENTITY()

    【讨论】:

    • 感谢回复,我应该把 insertcommandDet.ExecuteScaler() 放在哪里?在保存按钮单击事件中?或者我在哪里设置了 InsertCommand?
    • 在更改您建议的代码后,我还应该使用目前在单击按钮事件中使用的 sqlDataDet.Update 语句吗?
    • 再次感谢您的回复,请原谅初学者的愚蠢......但是代码是否适用于DataGridView,我的意思是OrdDetID如何获得实际ID(来自int ID代码)..?在 DataGridView 中,用户将输入多个产品的详细信息,例如 OrderID、ProductID、UnitPrice 和数量,输入的每条记录的结尾都会生成一个 OrdDetID,这就是为什么我对代码感到困惑...
    • 在按钮点击事件中,可以看到用户输入了什么内容,然后以上面的代码为指导。
    • 谢谢,我会尝试并告诉你。
    猜你喜欢
    • 1970-01-01
    • 2011-10-02
    • 2014-06-16
    • 2017-05-21
    • 2012-02-14
    • 1970-01-01
    • 2021-07-14
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多