简体   繁体   English

使用详细信息表中的外键将数据从C#插入到SQL Server 2005中的主/明细表中

[英]Insert Data to Master/Detail table in SQL Server 2005 from C# with Foreign key in Detail table

I need some help to make a order form in C#. 我需要一些帮助来在C#中制作订单。 My development environment is: 我的开发环境是:

  • Microsoft Visual Studio 2010 Ultimate Microsoft Visual Studio 2010 Ultimate
  • SQL Server Express Edition 2005 SQL Server Express Edition 2005
  • Programming Language C# 编程语言C#
  • Sample Database = NorthWind (Tables Orders and OrderDetails ) 示例数据库= NorthWind (表OrdersOrderDetails

I've create a form for order entry, which contain a textbox for OrderID , a combobox for Customer , DateTimePickers for OrderDate and ShippedDate and a DataGridView which contains columns OrderID (readonly) , ProductID , UnitPrice & Quantity . 我创建了一个订单输入表单,其中包含OrderID的文本框, Customer的组合框, OrderDateShippedDate DateTimePickers以及包含OrderID (readonly)ProductIDUnitPriceQuantity列的DataGridView。

In the form load event I've the following code: 在表单加载事件中,我有以下代码:

private void Inv2_Load(object sender, EventArgs e)
{
        SetComb();
        connectionString = ConfigurationManager.AppSettings["connectionString"];
        sqlConnection = new SqlConnection(connectionString);

        qryOrd = "Select OrderID, CustomerID, OrderDate, ShippedDate from Orders";
        qryOrdDet = "Select OrderID, ProductID, UnitPrice, Quantity from OrderDetails";

        sqlConnection.Open();
        sqlDataMaster = new SqlDataAdapter(qryOrd, sqlConnection);
        sqlDataDet = new SqlDataAdapter(qryOrdDet, sqlConnection);

        //SET MASTER INSERT/UPDATES
        command = new SqlCommand("INSERT INTO Orders ( CustomerID, OrderDate, ShippedDate) VALUES (@CustID, @OrdDt, @ShipDt) SELECT SCOPE_IDENTITY();");

        command.Parameters.Add("@OrdID", SqlDbType.NVarChar, 15);
        command.Parameters.Add("@CustID", SqlDbType.VarChar, 15);
        command.Parameters["@CustID"].Value = cmbCust.SelectedText;

        command.Parameters.Add("@OrdDt", SqlDbType.DateTime);
        command.Parameters["@OrdDt"].Value = dtOrdDt.Text;

        command.Parameters.Add("@ShipDt", SqlDbType.DateTime);
        command.Parameters["@ShipDt"].Value =dtShipDt.Text;

        sqlDataMaster.InsertCommand = command;
        //string id = command.ExecuteScalar().ToString();

        command = new SqlCommand("UPDATE Orders SET CustomerID = @CustID, OrderDate = @OrdDt, ShippedDate = @ShipDt WHERE OrderID = @OrdID");

        command.Parameters.Add("@OrdID", SqlDbType.NVarChar, 15, "OrderID").Value = txtOrdID.Text; 
        command.Parameters.Add("@CustID", SqlDbType.VarChar, 15, "CustomerID").Value = cmbCust.Text;
        command.Parameters.Add("@OrdDt", SqlDbType.DateTime).Value = dtOrdDt.Text;
        command.Parameters.Add("@ShipDt", SqlDbType.DateTime).Value = dtShipDt.Text;
        sqlDataMaster.UpdateCommand = command;

        //SET DETAILS INSERT/UPDATES
        commandDet = new SqlCommand("INSERT INTO OrderDetails (ProductID, UnitPrice, Quantity) VALUES (@PrdID, @Up,@Qty)");

        //commandDet.Parameters.Add("@OrdID", SqlDbType.NVarChar, 15, "OrderID").Value = txtOrdID.Text; ;  
        commandDet.Parameters.Add("@PrdId", SqlDbType.NVarChar, 5, "ProductID");
        commandDet.Parameters.Add("@Up", SqlDbType.VarChar, 50, "UnitPrice");
        commandDet.Parameters.Add("@Qty", SqlDbType.VarChar, 20, "Quantity");
        sqlDataDet.InsertCommand = commandDet;

        commandDet = new SqlCommand("UPDATE OrderDetails SET ProductID = @PrdID, UnitPrice = @Up, Quantity = @Qty WHERE OrderID = @OrdID");
        commandDet.Parameters.Add("@OrdID", SqlDbType.NVarChar, 15, "OrderID").Value = txtOrdID.Text; ;  
        commandDet.Parameters.Add("@PrdId", SqlDbType.NVarChar, 5, "ProductID");
        commandDet.Parameters.Add("@Up", SqlDbType.VarChar, 50, "UnitPrice");
        commandDet.Parameters.Add("@Qty", SqlDbType.VarChar, 20, "Quantity");
        sqlDataDet.UpdateCommand = commandDet;

        sqlComBldMaster = new SqlCommandBuilder(sqlDataMaster);
        sqlComBldDet = new SqlCommandBuilder(sqlDataDet);

        dt = new DataTable();
        dtDet = new DataTable();

        dt.Clear();
        dtDet.Clear();

        sqlDataMaster.FillSchema(dt, SchemaType.Source);
        sqlDataDet.FillSchema(dtDet, SchemaType.Source);

        dtDet.Columns["OrderID"].AutoIncrement = true;
        dtDet.Columns["OrderID"].AutoIncrementSeed = -1;
        dtDet.Columns["OrderID"].AutoIncrementStep = -1;
        ds = new DataSet();
        ds.Tables.Add(dt);
        ds.Tables.Add(dtDet);
        ds.EnforceConstraints = false;

        DataRelation rel = new DataRelation("OrdersRel", ds.Tables["Orders"].Columns["OrderID"], ds.Tables["OrderDetails"].Columns["OrderID"]);
        ds.Relations.Add(rel);

        bs = new BindingSource();
        bsDet = new BindingSource();

        bs.DataSource = ds;
        bs.DataMember = "Orders";

        bsDet.DataSource = ds;
        bsDet.DataMember = "OrderDetails";

        dgInvDet.AutoGenerateColumns = false;

        dgInvDet.Columns["ProductID"].DataPropertyName = "ProductID";
        ProductID.DataSource = dm.GetData("Select * from Products order by ProductName");
        ProductID.DisplayMember = "ProductName";
        ProductID.ValueMember = "ProductID";
        dgInvDet.Columns["UnitPrice"].DataPropertyName = "UnitPrice";
        dgInvDet.Columns["Quantity"].DataPropertyName = "Quantity";   

        dgInvDet.DataSource = bsDet;
    }

public void SetComb()
{
        cmbCust.DataSource = dm.GetData("Select * from Customers order by CompanyName");
        cmbCust.DisplayMember = "CompanyName";
        cmbCust.ValueMember = "CustomerId";
        cmbCust.Text = "";
}

Dm.GetData is the data access class method created for the purpose of just retrieving rows... Dm.GetData是为了只检索行而创建的数据访问类方法...

And in the Save button click event: 并在“ Save按钮单击事件中:

 private void btnSave_Click(object sender, EventArgs e)
 {
     dt.EndInit();

     rec = sqlDataMaster.Update(ds.Tables[0]);
     rec += sqlDataDet.Update(ds.Tables[1]);
     //recDet = sqlDataDet.Update(dt);

     ds.AcceptChanges();            

     MessageBox.Show(rec + " record(s) applied...." );

     ds.EnforceConstraints = true;
}

What I need is to save the data to SQL Server in respective table ( Orders and OrderDetails ) which my code can't seem to do. 我需要的是在我的代码似乎无法做的相应表( OrdersOrderDetails )中将数据保存到SQL Server。 It shows an error that foreign key cannot be null... because OrderDetails table also needs OrderID which is foreign key, and I am unable to understand how can I get the OrderID , as it is auto-generated after data is inserted into database. 它显示一个错误,外键不能为null ...因为OrderDetails表还需要OrderID这是外键,我无法理解如何获取OrderID ,因为它是在数据插入数据库后自动生成的。

Please help me on this problem to save the data in database with this foreign key issue... 请帮我解决这个问题,用这个外键问题将数据保存在数据库中......

Any help will be much appreciated. 任何帮助都感激不尽。

Thanks 谢谢

Ahmed 艾哈迈德

I can think of a couple options here. 我可以在这里想到几个选项。 First, you could modify your SQL on your master data adapter to perform the insert on both the order and order details tables at the same time (same goes for the update) and wrap them in a transaction (of course do the same on the updates...). 首先,您可以修改主数据适配器上的SQL以同时在订单和订单详细信息表上执行插入(同样适用于更新)并将它们包装在事务中(当然,在更新时也是如此) ...)。

Another option would be to handle the RowUpdated event (since it will fire on insert) of the data adapter, grab the ID, and then update the detail. 另一种选择是处理数据适配器的RowUpdated事件(因为它将在插入时触发),获取ID,然后更新细节。

Here is a brief example of what I was talking about in the first solution: 这是我在第一个解决方案中谈论的一个简短示例:

sqlDataMaster = new SqlDataAdapter(qryOrd, sqlConnection);
sqlDataDet = new SqlDataAdapter(qryOrdDet, sqlConnection);

//SET MASTER INSERT/UPDATES

command = new SqlCommand("DECLARE @tempOrderId numeric(38,0);" +
                            "BEGIN TRAN;" + 
                            "INSERT INTO Orders ( CustomerID, OrderDate, ShippedDate) VALUES (@CustID, @OrdDt, @ShipDt);" + 
                            "SELECT @tempOrderId = SCOPE_IDENTITY();" + 
                            "INSERT INTO OrderDetails (OrderId, ProductID, UnitPrice, Quantity) VALUES (@tempOrderId, @PrdID, @Up,@Qty);"
                            "IF @@Error <> 0 " + 
                            "   ROLLBACK TRANS" + 
                            "ELSE " + 
                            "   COMMIT TRANS";
    );
command.Parameters.Add("@OrdID", SqlDbType.NVarChar, 15);
command.Parameters.Add("@CustID", SqlDbType.VarChar, 15);
command.Parameters["@CustID"].Value = cmbCust.SelectedText;

command.Parameters.Add("@OrdDt", SqlDbType.DateTime);
command.Parameters["@OrdDt"].Value = dtOrdDt.Text;

command.Parameters.Add("@ShipDt", SqlDbType.DateTime);
command.Parameters["@ShipDt"].Value =dtShipDt.Text;

command.Parameters.Add("@PrdId", SqlDbType.NVarChar, 5, "ProductID");
command.Parameters.Add("@Up", SqlDbType.VarChar, 50, "UnitPrice");
command.Parameters.Add("@Qty", SqlDbType.VarChar, 20, "Quantity");
sqlDataMaster.InsertCommand = command;

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM