Warning: file_get_contents(/data/phpspider/zhask/data//catemap/7/sql-server/22.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# TSQL插入外键链接的数据_C#_Sql Server_Foreign Keys - Fatal编程技术网

C# TSQL插入外键链接的数据

C# TSQL插入外键链接的数据,c#,sql-server,foreign-keys,C#,Sql Server,Foreign Keys,假设我有两张桌子 RDB_数据实体 DataEntityId Name Created Modified ... DataInstanceId DataEntityId RDB_数据实例 DataEntityId Name Created Modified ... DataInstanceId DataEntityId 因此,RDB_数据实例通过其DataEntityId列上的外键连接到RDB_数据实体 假设我想在同一事务中将数据插入两个表中。我的代码如下: using (var con

假设我有两张桌子

RDB_数据实体

DataEntityId
Name
Created
Modified
...
DataInstanceId
DataEntityId
RDB_数据实例

DataEntityId
Name
Created
Modified
...
DataInstanceId
DataEntityId
因此,
RDB_数据实例
通过其
DataEntityId
列上的外键连接到
RDB_数据实体

假设我想在同一事务中将数据插入两个表中。我的代码如下:

using (var con = new SqlConnection("data source=speedy;initial catalog=mydb;user id=myuser;password=mypass"))
{
   con.Open();

   using (var tran = con.BeginTransaction())
   {
      SqlCommand i1 = new SqlCommand("insert into RDB_DataEntities (Name,IsSchema,Created,Modified,RequireCaptcha,UniqueByEmail,UniqueByMac) values ('hi',0,GetDate(),GetDate(),0,0,0)", con, tran);

      i1.ExecuteNonQuery();

      SqlCommand i2 = new SqlCommand("select SCOPE_IDENTITY() as newid", con, tran);
      var id = int.Parse(i2.ExecuteScalar().ToString());

      SqlCommand i3 = new SqlCommand("insert into RDB_DataInstances (DataEntityId) values (" + id + ")", con, tran);
      i3.ExecuteScalar();
      tran.Commit();
   }
}
为什么会抛出外键错误

INSERT语句与外键约束冲突 “FK_RDB_数据实例_RDB_数据实体”。冲突发生在 数据库'NMSS_CMS',表'dbo.RDB_DataEntities',列 “DataEntityId”

事务不应该知道我正在根据我刚才在当前事务上下文中所做的插入插入外键吗?我走远了吗


您是如何做到这一点的?

因为当您使用两个不同的命令上下文时,
SCOPE\u IDENTITY()
将不起作用(根据定义,它是一个单独的作用域)。您可以将第二个查询附加到第一个查询,然后运行
ExecuteScalar()
,如下所示:

SqlCommand i1 = new SqlCommand("insert into RDB_DataEntities (Name,IsSchema,Created,Modified,RequireCaptcha,UniqueByEmail,UniqueByMac) values ('hi',0,GetDate(),GetDate(),0,0,0);select SCOPE_IDENTITY() as newid;",con,tran);                 
var id=int.Parse(i1.ExecuteScalar().ToString()); 
编辑:只是想把正在发生的事情的T-SQL版本放在一起

DECLARE @newid int

BEGIN TRANSACTION

insert into RDB_DataEntities 
    (Name,IsSchema,Created,Modified,RequireCaptcha,UniqueByEmail,UniqueByMac) 
values 
    ('hi',0,GetDate(),GetDate(),0,0,0)

SELECT @newid = SCOPE_IDENTITY()

insert into RDB_DataInstances 
    (DataEntityId) 
values 
    (@newid)

COMMIT TRANSACTION

如果我了解您的问题,这里有两种可能的解决方案:

  • 您可以设置事务隔离级别,并使用readuncommitted/NOLOCK对事务中先前插入的记录执行脏读(有关更多信息,请参阅本文)

  • 您只需在代码中创建Guid,并将其作为SqlCommand参数手动插入两个表中,而不是在第一次插入后使用
    SCOPE\u IDENTITY()
    。(我的首选)


  • 我删除了外键并重新创建了它,它开始工作。

    另一个解决方案:使用output子句。为自己保存一个查询。SCOPE_IDENTITY()肯定是双向的。我已经调试过,以确保我的var id肯定有一个整数值。如果你得到了正确的值,那么我同意它应该工作。您尝试执行的T-SQL版本具有逻辑意义。它不会在您的第一次插入时发生,是吗?也就是说,你没有把FK设置错方向。。。