C# SqlException:insert语句与外键约束冲突

C# SqlException:insert语句与外键约束冲突,c#,sql-server,database,sqlexception,C#,Sql Server,Database,Sqlexception,我试图向数据库中的两个表添加值,一个包含主键,另一个完全是外键。我尝试过先使用主键,然后使用外键添加到表中,但没有效果 表单上执行insert命令的代码: int rowsAffected = ProjectDal.AddBookingInfo(GroomOptionComboBox.Text, HairComboBox.Text, TeethComboBox.Text, NailsComboBox.Text, AppointmentDateTimePicker.Text, CustomerSt

我试图向数据库中的两个表添加值,一个包含主键,另一个完全是外键。我尝试过先使用主键,然后使用外键添加到表中,但没有效果

表单上执行insert命令的代码:

int rowsAffected = ProjectDal.AddBookingInfo(GroomOptionComboBox.Text, HairComboBox.Text, TeethComboBox.Text, NailsComboBox.Text, AppointmentDateTimePicker.Text, CustomerStatusComboBox.Text, Convert.ToString(StartingTime), Convert.ToString(FinishTime), Convert.ToString(duration), AllPrice);

if (rowsAffected > 0)
{
    MessageBox.Show("Booking successfully added", "Success");
    int rowsAffected2 = ProjectDal.AddBooking(Convert.ToInt32(DogIDComboBox.Text), Convert.ToInt32(ClientIDComboBox.Text));

    if (rowsAffected2 > 0)
    {
        MessageBox.Show("Booking successfully added", "Success");
    }
    else
    {
        MessageBox.Show("Booking not successful", "Failure");
    }
}
else
{
    MessageBox.Show("Booking not successful", "Failure");
}
项目DAL中的代码:

public static int AddBooking(int DogID, int ClientID)
{
    using (SqlConnection connection = new SqlConnection(_connectionstring))
    {
        connection.Open();

        SqlCommand insertClientCommand = new SqlCommand();
        insertClientCommand.Connection = connection;
        insertClientCommand.CommandType = System.Data.CommandType.StoredProcedure;
        insertClientCommand.CommandText = "AddBooking";

        insertClientCommand.Parameters.Add(new SqlParameter("@DogID", DogID));
        insertClientCommand.Parameters.Add(new SqlParameter("@ClientID", ClientID));

        int rowsAffected = insertClientCommand.ExecuteNonQuery();

        connection.Close();

        return rowsAffected;
    }
}

public static int AddBookingInfo(string GroomOption, string Hair, string Teeth, string Nails, string DateOfAppointment, string IsFirstTime, string StartTime, string FinishTime, string Duration, double Price)
{
    using (SqlConnection connection = new SqlConnection(_connectionstring))
    {
        connection.Open();

        SqlCommand insertClientCommand = new SqlCommand();
        insertClientCommand.Connection = connection;
        insertClientCommand.CommandType = System.Data.CommandType.StoredProcedure;
        insertClientCommand.CommandText = "AddBookingInfo";

        insertClientCommand.Parameters.Add(new SqlParameter("@GroomOption", GroomOption));
        insertClientCommand.Parameters.Add(new SqlParameter("@Hair", Hair));
        insertClientCommand.Parameters.Add(new SqlParameter("@Teeth", Teeth));
        insertClientCommand.Parameters.Add(new SqlParameter("@Nails", Nails));
        insertClientCommand.Parameters.Add(new SqlParameter("@DateOfAppointment", DateOfAppointment));
        insertClientCommand.Parameters.Add(new SqlParameter("@IsFirstTime", IsFirstTime));
        insertClientCommand.Parameters.Add(new SqlParameter("@StartTime",StartTime));
        insertClientCommand.Parameters.Add(new SqlParameter("@FinishTime", FinishTime));
        insertClientCommand.Parameters.Add(new SqlParameter("@Duration", Duration));
        insertClientCommand.Parameters.Add(new SqlParameter("@Price", Price));

        int rowsAffected = insertClientCommand.ExecuteNonQuery();

        connection.Close();

        return rowsAffected;
    }
}
这两个表的SQL语句都是:

CREATE TABLE [dbo].[BookingInfo] 
(
    [BookingID]         INT IDENTITY (101, 1) NOT NULL,
    [GroomOption]       NCHAR(10)    NULL,
    [Hair]              NCHAR(10)    NULL,
    [Teeth]             NCHAR(10)    NULL,
    [Nails]             NCHAR(10)    NULL,
    [DateOfAppointment] NVARCHAR(50) NULL,
    [IsFirstTime]       NCHAR(10)    NULL,
    [StartTime]         NCHAR(10)    NULL,
    [FinishTime]        NCHAR(10)    NULL,
    [Duration]          NCHAR(10)    NULL,
    [Price]             FLOAT(53)    NULL,

    PRIMARY KEY CLUSTERED ([BookingID] ASC)
)

CREATE TABLE [dbo].[Booking] 
(
    [BookingID] INT IDENTITY (101, 1) NOT NULL,
    [DogID]     INT NOT NULL,
    [ClientID]  INT NOT NULL,

    PRIMARY KEY CLUSTERED ([BookingID] ASC),

    CONSTRAINT [FK_Booking_ToDogInfo] 
        FOREIGN KEY ([DogID]) REFERENCES [dbo].[DogInfo] ([DogID]),
    CONSTRAINT [FK_Booking_ToOwner] 
        FOREIGN KEY ([ClientID]) REFERENCES [dbo].[Owner] ([ClientID]), 
    CONSTRAINT [FK_Booking_ToBookingInfo] 
        FOREIGN KEY ([BookingID]) REFERENCES [dbo].[BookingInfo]([BookingID])
)

您的代码有很多问题:

  • BookingID
    表上的
    BookingID
    不应该是
    IDENTITY
    列,也不应该是主键(至少不应该自己),因为它只接受来自
    BookingInfo
    的外键。您可能希望使其成为另一列的主键
  • 因此,您需要从
    bookininfo
    insert返回ID,然后传递到另一个insert
其他注意事项:

  • 仔细选择数据类型:
    nchar
    是固定长度,将填充空格,使用
    nvarchar
    代替可变长度。日期应在
    date
    datetime
    列中。布尔值应该放在
    bit
    列中。任何涉及金钱的东西都必须是十进制的,而不是浮动的
  • 指定参数类型、长度和精度
  • 使用
    块将
    SqlCommand
    放入
您的SQL代码将如下所示:

创建或更改过程AddBookingInfo
@新郎卡(10)
.....
@bookingfoid int输出
作为
插入BookingInfo
(选项…)
值(@GroomOption,…);
选择CAST(SCOPE_IDENTITY()为int);
去
你的C#side看起来像这样:

public static int AddBookingInfo(字符串修饰选项、字符串头发、字符串牙齿、字符串指甲、字符串使用日期、字符串IsFirstTime、字符串开始时间、字符串完成时间、字符串持续时间、双倍价格)
{
正在使用(SqlConnection=newsqlconnection(_connectionstring))
使用(SqlCommand insertClientCommand=newsqlcommand(“addbookininfo”,connection))
{
insertClientCommand.CommandType=System.Data.CommandType.StoredProcess;
insertClientCommand.Parameters.Add(“@GroomOption”,SqlDbType.VarChar,10)。Value=GroomOption;
//……等等
connection.Open();
return(int)insertClientCommand.ExecuteScalar();//结果是ID
}
}
公共静态int-AddBooking(int-BookingInfoId、int-DogID、int-ClientID)
{
正在使用(SqlConnection=newsqlconnection(_connectionstring))
使用(SqlCommand insertClientCommand=newsqlcommand(“AddBooking”,connection))
{
insertClientCommand.CommandType=System.Data.CommandType.StoredProcess;
insertClientCommand.Parameters.Add(“@bookinfoid”,SqlDbType.Int)。Value=bookinfoid;
insertClientCommand.Parameters.Add(“@DogID”,SqlDbType.Int).Value=DogID;
insertClientCommand.Parameters.Add(“@ClientID”,SqlDbType.Int)。Value=ClientID;
connection.Open();
int rowsAffected=insertClientCommand.ExecuteNonQuery();
connection.Close();
返回受影响的行;
}
}

老实说,您的数据模型似乎有些可疑:
预订
预订信息
之间有什么区别,它们是代表不同的概念还是应该在同一个表中


另外,
Duration
应该是一个计算列,因为它可以从其他列计算,并且当您实际需要数据时,不应该将列声明为
NULL

从调用AddBooking()的位置?根据您的代码,我认为您必须首先调用AddBooking(),并将BookingID传递给AddBookingInfo().Rel-不要使用-这就是您的参数创建方法有效的功能。BookingInfo有一个标识列(定义很差,但这是一组不同的问题)。您没有发布AddBookingInfo存储过程,但它如何将新插入行的值返回到应用程序?在应用程序代码中,您在哪里捕获该ID,然后将其传递给添加预订行时使用?现在我看了更多,您在两个表中使用标识列时遇到了问题。看来你对如何设计桌子有些困惑。不能有(或期望)两个独立的标识列生成相同(即同步)的值,并将其中一个用作另一个的外键。由于您当前已构建表,Booking.BookingID不能是标识列-它是BookingInfo的FK,必须由应用程序填充。