2014-01-13 34 views
0

我有我的SQL Server CE數據庫如下表:從父表到子表的主鍵的應用

訂單

OrderID (handled my DBMS) 
CustomerID 
OrderDate 

ORDER_DETAILS

OrderID (from the ORDERS table) 
ProductID 
OrderQTY 

我目前使用2個插入查詢將新訂單添加到數據庫。第一個將訂單插入到ORDERS表中並允許DBMS創建OrderID,第二個將OrderID用於插入到ORDER_DETAILS表中。

我在下面使用的方法看起來很klunky,並且可能容易出現併發問題。當新記錄插入到ORDERS表中時,是否有辦法讓DBMS處理爲ORDER_DETAILS表創建正確的OrderID

這是我用來運行插入查詢C#:

public int InsertOrder(Order order) 
    { 
     DBConnection connection = DBConnection.getInstance(); 
     connection.conn.Open(); 
     using (SqlCeCommand query = new SqlCeCommand(OrderCommandList.cmdInsertOrderHeader, connection.conn)) 
     { 
      query.Parameters.AddWithValue("@CustomerID", order.CustomerID); 
      query.Parameters.AddWithValue("@OrderDate", order.OrderDate); 
      query.ExecuteNonQuery(); 
     } 

     //retrieves the PK for the recently inserted record 
     int newOrderPK = 0; 
     using(SqlCeCommand cmdGetIdentity = new SqlCeCommand("SELECT @@IDENTITY", connection.conn)) 
     { 
      newOrderPK = Convert.ToInt32(cmdGetIdentity.ExecuteScalar()); 
     } 
     connection.conn.Close(); 
     InsertOrderDetails(order, newOrderPK); 
     return newOrderPK; 
    } 

    //inserts all the order details associated with the Order object 
    private void InsertOrderDetails(Order order, int orderForeignKey) 
    { 
     foreach (OrderDetail od in order.OrderLineItems) 
     { 
      DBConnection connection = DBConnection.getInstance(); 
      connection.conn.Open(); 
      using (SqlCeCommand query = new SqlCeCommand(OrderCommandList.cmdInsertOrderDetails, connection.conn)) 
      { 
       query.Parameters.AddWithValue("@OrderID", orderForeignKey); 
       query.Parameters.AddWithValue("@ProductID", od.ProductID); 
       query.Parameters.AddWithValue("@OrderQty", od.QtyOrdered); 
       query.ExecuteNonQuery(); 
      } 
      connection.conn.Close(); 
     } 
    } 
+0

您有此問題標記爲C#,因此知道您目前使用哪些C#代碼來保存數據可能很有用。這可能會影響最佳的處理方式。 – jmcilhinney

回答

0

更改您的存儲過程來選擇所產生的標識值,並將其使用SELECT SCOPE_IDENTITY();而非SELECT @@IDENTITY;。其實,最好是使用OUTPUT參數,但現在我假設你將繼續使用SELECT。例如

INSERT dbo.Orders(CustomerID,OrderDate) SELECT @CustomerID,@OrderDate; 
SELECT ID = SCOPE_IDENTITY(); 

然後,而不是ExecuteNonQuery()用於插入,然後爲SELECT @@IDENTITY一個單獨的命令,你只需要一個ExecuteScalar執行這兩個。

你可以做得比使用TVPs更好,你可以通過單個存儲過程發送訂單和所有詳細信息行。然而,行政長官有點過時 - 不確定它是否支持TVP。你應該考慮使用Express/LocalDB。

+0

Scope_identity不適用於sql server compact,只有選項是@@ identity,並且對同一個打開的連接發出第二個select是很重要的,並且每個命令只允許一個語句 – ErikEJ

相關問題