使用 SQL 和 C# 将表 1 的主键分配为表 2 中的外键

Posted

技术标签:

【中文标题】使用 SQL 和 C# 将表 1 的主键分配为表 2 中的外键【英文标题】:Assign Primary Key of Table 1 as a Foreign Key in Table 2 using SQL and C# 【发布时间】:2016-01-19 12:56:23 【问题描述】:

我有使用自动递增主键 Member_Id 和 Office_Id 的表 Member 和 Office。我正在向表中插入数据,但希望将成员表的主键作为外键插入到 Office 表中,以便将成员分配给办公室记录。请协助。下面是我用于插入记录的代码的 sn-p,但我只是不知道如何链接这两个表。

protected void capture()
    
        string CS = ConfigurationManager.ConnectionStrings["MyDatabase"].ConnectionString;
        using (SqlConnection conn = new SqlConnection(CS))
        
            conn.Open();

            SqlCommand com = new SqlCommand();
            SqlParameter myParam = new SqlParameter();

            com.CommandText = "INSERT into Member(Appointment_Number, Initials, Surname, Designation) VALUES (@Appointment_Number, @Initials, @Surname, @Designation)";
            com.Parameters.AddWithValue("@Appointment_Number", txtAppointmentNumber.Text);
            com.Parameters.AddWithValue("@Initials", txtInitials.Text);
            com.Parameters.AddWithValue("@Surname", txtSurname.Text);
            com.Parameters.AddWithValue("@Designation", ddlDesignation.Text);              
            com.Connection = conn;
            com.ExecuteNonQuery();
            com.Parameters.Clear();

           //Insert records into the office table                
            com.CommandText = "INSERT into Offices(Office_Number, Status, Building, Branch, Floor) VALUES (@Office_Number, @Status, @Building, @Branch, @Floor)";
            com.Parameters.AddWithValue("@Office_Number", txtOffNo.Text);
            com.Parameters.AddWithValue("@Status", ddlOStatus.Text);
            com.Parameters.AddWithValue("@Building", ddlBuilding.Text);
            com.Parameters.AddWithValue("@Branch", ddlBranch.Text);
            com.Parameters.AddWithValue("@Floor", ddlFloors.Text);               
            com.Connection = conn;
            com.ExecuteNonQuery();
            com.Parameters.Clear();               

            if (IsPostBack)
            
                Response.Redirect("~/Pages/MemberDetails.aspx");

            
                
    

【问题讨论】:

对不起,但关系似乎是:一个 Office 有零到 N 个 Member。对?然后是 Member 表需要 OfficeID 外键,而不是相反。 【参考方案1】:

我想,你想在办公室和成员 1 到 n 之间建立关系。

为此,让我们在 members 表中添加 officeid 字段,在 member 之前插入 office 记录并像这样更改代码;

protected void capture()
    
        string CS = ConfigurationManager.ConnectionStrings["MyDatabase"].ConnectionString;
        using (SqlConnection conn = new SqlConnection(CS))
        
            conn.Open();

            SqlCommand com = new SqlCommand();
            SqlParameter myParam = new SqlParameter();

            //Insert records into the office table                
            com.CommandText = "INSERT into Offices(Office_Number, Status, Building, Branch, Floor) VALUES (@Office_Number, @Status, @Building, @Branch, @Floor)";
            com.Parameters.AddWithValue("@Office_Number", txtOffNo.Text);
            com.Parameters.AddWithValue("@Status", ddlOStatus.Text);
            com.Parameters.AddWithValue("@Building", ddlBuilding.Text);
            com.Parameters.AddWithValue("@Branch", ddlBranch.Text);
            com.Parameters.AddWithValue("@Floor", ddlFloors.Text);
            com.Connection = conn;
            com.ExecuteNonQuery();
            com.Parameters.Clear();

            com.CommandText = "select max(Office_Id) from Offices";
            int officeid = Convert.ToInt32(com.ExecuteScalar());

            com.CommandText = "INSERT into Member(officeid,Appointment_Number, Initials, Surname, Designation) VALUES (@officeid,@Appointment_Number, @Initials, @Surname, @Designation)";
            com.Parameters.AddWithValue("@officeid", officeid);
            com.Parameters.AddWithValue("@Appointment_Number", txtAppointmentNumber.Text);
            com.Parameters.AddWithValue("@Initials", txtInitials.Text);
            com.Parameters.AddWithValue("@Surname", txtSurname.Text);
            com.Parameters.AddWithValue("@Designation", ddlDesignation.Text);
            com.Connection = conn;
            com.ExecuteNonQuery();
            com.Parameters.Clear();

            if (IsPostBack)
            
                Response.Redirect("~/Pages/MemberDetails.aspx");

            
                
    

【讨论】:

【参考方案2】:

在您插入第一个表后,使用相同的连接 SELECT SCOPE_IDENTITY() 获取刚刚创建的自动分配的标识值。然后,您可以使用它插入到第二个表中。

使用 SCOPE_IDENTITY() 将确保您始终获得刚刚创建的 id。如果您的系统正被多个用户同时使用,您不想冒险获取另一个恰好与您同时插入数据的用户创建的身份值。

例如在您第一次插入之后:

com.CommandText = "SELECT SCOPE_IDENTITY()";
int my_id_just_created = Convert.ToInt32(com.ExecuteScalar());

【讨论】:

我刚刚在插入到第一个表后使用了上述命令,但它给出了 System.InvalidCastException 错误,提示“对象不能从 DBNull 转换为其他类型”。【参考方案3】:

最简单的方法可能是先插入Office 表,获取范围标识,然后将其放入member 插入的FK 中。要获取范围标识,只需使用以下语法:

INSERT INTO YourTable
(val1, val2, val3 ...)
VALUES(@val1, @val2, @val3...);
SELECT SCOPE_IDENTITY();

然后您使用com.ExecuteScalar(),它将返回一个带有Office 表的PK 的Int,您可以将其用作Member 表的FK。

【讨论】:

以上是关于使用 SQL 和 C# 将表 1 的主键分配为表 2 中的外键的主要内容,如果未能解决你的问题,请参考以下文章

在 SQL Server CE 和 C# 中获取新插入行的主键?

使用唯一随机值更新sql表中的所有行,而不使用c#中的主键或唯一键

在 postgres 中更新具有大量删除的表的主键序列

如何在数据库C#中查找表的主键

如何在 C# 中获取 DataGridView 中的主键?

存储过程:将表名转换为表变量