C# 在不知道主表主键的情况下,在具有外键关系的表中插入2行
我在SQL Server Manager 2014中有以下数据库方案 我正在Visual Studio中制作一个C-windows应用程序,我想插入一个新订单行和一个新订单。问题是这两个表的主键都是在服务器管理器中自动生成的,因此我还没有确定order表的主键的值,但我需要该值来填充orderLine列的外键。如何插入这两行C# 在不知道主表主键的情况下,在具有外键关系的表中插入2行,c#,sql,sql-server,database,visual-studio,C#,Sql,Sql Server,Database,Visual Studio,我在SQL Server Manager 2014中有以下数据库方案 我正在Visual Studio中制作一个C-windows应用程序,我想插入一个新订单行和一个新订单。问题是这两个表的主键都是在服务器管理器中自动生成的,因此我还没有确定order表的主键的值,但我需要该值来填充orderLine列的外键。如何插入这两行 种类属性SCOPE\u IDENTITY返回插入同一范围内标识列的最后一个标识值。作用域是一个模块:存储过程、触发器、函数或批处理。因此,如果两条语句位于同一存储过程、函数
种类属性SCOPE\u IDENTITY返回插入同一范围内标识列的最后一个标识值。作用域是一个模块:存储过程、触发器、函数或批处理。因此,如果两条语句位于同一存储过程、函数或批处理中,则它们位于同一范围内 您可以使用SqlCommand.ExecuteScalar执行insert命令,并在一个查询中检索新ID
using (var con = new SqlConnection(ConnectionString)) {
int newOrderID;
var cmd = "INSERT INTO Order (column_name) VALUES (@Value) ;SELECT CAST(scope_identity() AS int)";
using (var insertCommand = new SqlCommand(cmd, con)) {
insertCommand.Parameters.AddWithValue("@Value", "bar");
con.Open();
newOrderID = (int)insertCommand.ExecuteScalar();
}
}
这将允许您捕获最后生成的OrderId,并在OrderLine表的Insert语句中使用它
另一个选项是使用以下SQL代码:
string command = "INSERT INTO Order(totalPrice) OUTPUT INSERTED.ID VALUES(@totalPrice)" // this will be a parameter from your code
然后可以从以下位置获取OrderId:
Int32 orderId = (Int32) command.ExecuteScalar();
如果使用任何形式的直接SQL,则需要在插入订单后立即接收SCOPE_IDENTITY值,然后使用该值插入行 插入命令 选择SCOPE_IDENTITY作为NewId;或返回范围\标识;或者声明@OrderId INT=SCOPE\u标识; 插入订单行
否则,使用Entity Framework,它将自动检索新id并分配给依赖项。虽然scope_id对单行适用,但您确实应该学会使用output子句,因为scope_id对使用单个sql语句插入的多行无效 有关使用output子句的简单示例,请参见此 显然,这也允许您检索不仅仅是标识值 增加 同样有用的是2012年新增的序列功能,而不是使用标识。如果您的数据库来自其他数据库,这似乎是一个更自然的解决方案
如果您想在多个表之间共享一个序列,序列非常有用-尽管这是一种不常见的设计,我已经使用过几次了。您使用什么来执行插入?通常,您必须插入订单,重新接收新ID,然后插入订单行。您永远不能在一条语句中插入两个表。也许你可以想出一个存储过程,一次插入一个。@jtimperley,当我没有Id或唯一行要搜索时,我怎么能收到我的新Id?@Andrew with,我的意思是用1c方法,我编辑了那个部分。@ComputerDude你不应该搜索新Id,它们由SQL Server提供,可以作为单个操作的作用域标识,也可以通过向批量操作添加“OUTPUT insert.OrderId”来提供。一个更具体的方法需要知道您选择了100个.NET数据访问方法中的哪一个。有人知道我为什么被否决吗?我的问题不清楚吗?