事务范围主键插入,然后插入外键插入 ->插入 2 个主键行

本文关键字:插入 然后 范围 事务 | 更新日期: 2023-09-27 18:34:02

我正在尝试创建一个全有或全无的大型事务范围。我插入了大约 2000 条记录。我想插入主键,读回它,然后在事务中插入外键,然后在发生错误时回滚所有内容。

PSS_InvoiceTotal表具有 PK -> 发票总计 ID

PSS_Invoices表有一个 FK -> 发票总计 ID

每次创建 2 个主键行时,问题出在数据库中。我在没有外键插入的情况下运行了代码,它工作正常。有没有办法防止它产生 2 个主键行?

        using (TransactionScope scope = new TransactionScope(TransactionScopeOption.Required))
        {
            try
            {
                conn.Open();
                foreach (var uniqueSupply in supplyList.GroupBy(a=>a.ShipTo))
                {
                    //reset total 
                    total = 0;
                    var supplyListByShipTo = supplyList.Where(a => a.ShipTo == uniqueSupply.Key);
                    foreach (var addSupply in supplyListByShipTo)
                    {
                        total = total + addSupply.Amount;
                    }
                    StringBuilder insert_PSS_InvoiceTotal = new StringBuilder();
                    //save total to DB
                    insert_PSS_InvoiceTotal = new StringBuilder();
                    insert_PSS_InvoiceTotal.Append("INSERT INTO [PSS_InvoiceTotal] ");
                    insert_PSS_InvoiceTotal.Append("([InvoiceDate],[Amount]) ");
                    insert_PSS_InvoiceTotal.Append("VALUES(@DateTime, @Amount) ");
                    insert_PSS_InvoiceTotal.Append("SELECT SCOPE_IDENTITY() AS [InvoiceTotalID];");
                    cmd = new SqlCommand(insert_PSS_InvoiceTotal.ToString(), conn);
                    cmd.Parameters.AddWithValue("@DateTime", DateTime.Now);
                    cmd.Parameters.AddWithValue("@Amount", total);
                    //ToDo: Add back in later
                    cmd.ExecuteNonQuery();
                    SqlDataReader dr = cmd.ExecuteReader();
                    if (dr.Read())
                    {
                        InvoiceTotalID = Convert.ToInt32(dr["InvoiceTotalID"].ToString());
                    }
                    dr.Close();
                    foreach (var supply in supplyListByShipTo)
                    {
                        StringBuilder insert_PSS_Invoice = new StringBuilder();
                        //Create the SQL command
                        insert_PSS_Invoice.Append("INSERT INTO [PSS_Invoices] ");
                        insert_PSS_Invoice.Append("([ClientDetailId],Amount],InvoiceTotalId)");
                        insert_PSS_Invoice.Append("VALUES(");
                        insert_PSS_Invoice.Append("@Amount,@InvoiceTotalId)");
                        cmd = new SqlCommand(insert_PSS_Invoice.ToString(), conn);
                        cmd.Parameters.AddWithValue("@Amount", 4.44);
                        cmd.Parameters.AddWithValue("@InvoiceTotalId", InvoiceTotalID);
                        //ToDo: put back in later
                        cmd.ExecuteNonQuery();
                    }
                }
                //Close connection
                conn.Close();
                //Commit and Dispose Transaction
                scope.Complete();
                scope.Dispose();
            }
            catch (Exception ex)
            {
                //Rollback Transaction
                scope.Dispose();
                return Json(new { success = false, message = ex.ToString() }, JsonRequestBehavior.AllowGet);
            }
        }

事务范围主键插入,然后插入外键插入 ->插入 2 个主键行

尝试评论

 //ToDo: Add back in later
 //cmd.ExecuteNonQuery();

也许你可以考虑使用 INSERT 命令的 OUTPUT 选项来获取插入执行的主键。这样您就不必回读它。查看此链接: https://msdn.microsoft.com/en-us/library/ms177564.aspx

此外,您可能需要向命令对象添加输出参数以获取该信息。

相关文章: