我的SQL Server CE数据库中有以下表格:
ORDERS
OrderID (handled my DBMS)
CustomerID
OrderDate
ORDER_DETAILS
OrderID (from the ORDERS table)
ProductID
OrderQTY
我目前使用2个插入查询来向数据库添加新订单。第一个将订单插入ORDERS
表并允许DBMS创建OrderID
,第二个使用提供的OrderID
插入ORDER_DETAILS
表。
我在下面使用的方法看起来非常笨拙,并且可能容易受到并发问题的影响。当新记录插入OrderID
表时,有没有办法让DBMS处理ORDER_DETAILS
表的正确ORDERS
的创建?
这是我用来运行插入查询的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 :(得分:0)
更改存储过程以选择生成的标识值,并使用SELECT SCOPE_IDENTITY();
而不是SELECT @@IDENTITY;
。实际上,最好是使用OUTPUT参数,但现在我假设您将继续使用SELECT
。 e.g。
INSERT dbo.Orders(CustomerID,OrderDate) SELECT @CustomerID,@OrderDate;
SELECT ID = SCOPE_IDENTITY();
然后,对于插入而不是ExecuteNonQuery()
,而不是SELECT @@IDENTITY
的单独命令,您只需要一个ExecuteScalar
来执行这两个命令。
使用TVP可以做得更好,您可以使用单个存储过程发送订单和所有详细信息行。然而,CE有点过时 - 不确定它是否支持TVP。您应该考虑使用Express / LocalDB。