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

时间:2012-12-07 14:15:03

标签: c# sql-server datagridview foreign-key-relationship

我需要一些帮助来在C#中制作订单。我的开发环境是:

  • Microsoft Visual Studio 2010 Ultimate
  • SQL Server Express Edition 2005
  • 编程语言C#
  • 示例数据库= NorthWind(表OrdersOrderDetails

我创建了一个订单输入表单,其中包含OrderID的文本框,Customer的组合框,OrderDateShippedDate的DateTimePickers以及DataGridView包含列OrderID (readonly)ProductIDUnitPrice& Quantity

在表单加载事件中,我输入以下代码:

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是为了只检索行而创建的数据访问类方法...

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;
}

我需要的是将数据保存到我的代码似乎无法执行的相应表(OrdersOrderDetails)中的SQL Server。它显示外键不能为空的错误...因为OrderDetails表还需要OrderID这是外键,我无法理解如何获取OrderID,因为数据插入数据库后自动生成。

请帮我解决这个问题,将此数据保存在数据库中以解决此外键问题......

非常感谢任何帮助。

由于

艾哈迈德

1 个答案:

答案 0 :(得分:4)

我可以在这里想到几个选项。首先,您可以修改主数据适配器上的SQL以同时在订单和订单详细信息表上执行插入(同样适用于更新)并将它们包装在事务中(当然,在更新时也是如此) ...)。

另一种选择是处理数据适配器的RowUpdated事件(因为它将在插入时触发),获取ID,然后更新细节。

以下是我在第一个解决方案中谈论的一个简短示例:

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;