如果“DELETE 语句与 REFERENCE 约束冲突”,则取消“删除”事件
本文关键字:删除 事件 取消 约束 语句 DELETE REFERENCE 如果 冲突 | 更新日期: 2023-09-27 18:34:11
我使用的是System.Data.EntityClient
而不是简单的System.Data.SqlClient
我是实体框架的新手,所以请原谅我的无知,请不要提供神秘的回应,因为我没有必要的背景信息来理解它们。
我做了几个小时的研究,但找不到解决我问题的正确答案组合。
问题:
当触发"删除"事件时,页面会引发此错误:
DELETE 语句与 REFERENCE 约束冲突
我想捕获该错误并让它在页面上填充一个标签,上面写着
无法删除此客户
我的ASP页面:
<asp:Content ID="Content2" ContentPlaceHolderID="ContentPlaceHolder1" runat="server">
<p>
<asp:DetailsView ID="CustomerDetail" runat="server"
DataSourceID="CustomerSqlDataSource" Height="50px"
Width="215px" Visible="False" AutoGenerateRows="False"
OnModeChanged="CustomerDetail_ModeChanged">
<Fields>
<asp:BoundField DataField="FirstName" HeaderText="First Name:" />
<asp:BoundField DataField="LastName" HeaderText="Last Name:" />
<asp:BoundField DataField="City" HeaderText="City:" />
<asp:BoundField DataField="State" HeaderText="State" />
<asp:CommandField ShowInsertButton="True" />
</Fields>
</asp:DetailsView>
</p>
<asp:Button ID="NewCustomerButton" runat="server" Text="New Customer" OnClick="NewCustomerButton_Click" />
<p>
<asp:Label ID="DeleteLabel" runat="server" Text="" Visible="false"/>
<asp:GridView ID="CustomerGrid" runat="server" AutoGenerateColumns="False"
DataKeyNames="CustomerId" DataSourceID="CustomerSqlDataSource"
OnSelectedIndexChanged="CustomerGrid_SelectedIndexChanged" >
<Columns>
<asp:CommandField ShowDeleteButton="True" ShowEditButton="True" />
<asp:BoundField DataField="FirstName" HeaderText="FirstName" SortExpression="FirstName" />
<asp:BoundField DataField="LastName" HeaderText="LastName" SortExpression="LastName" />
<asp:BoundField DataField="City" HeaderText="City" SortExpression="City" />
<asp:BoundField DataField="State" HeaderText="State" SortExpression="State" />
</Columns>
</asp:GridView>
<br />
<br />
<asp:SqlDataSource ID="CustomerSqlDataSource" runat="server"
ConnectionString="<%$ ConnectionStrings:ITP236-InventoryConnectionString %>"
DeleteCommand="DELETE FROM [Customer] WHERE [CustomerId] = @CustomerId"
InsertCommand="INSERT INTO [Customer] ([FirstName], [LastName], [City], [State])
VALUES (@FirstName, @LastName, @City, @State)"
SelectCommand="SELECT [CustomerId], [FirstName], [LastName], [City], [State] FROM [Customer]"
UpdateCommand="UPDATE [Customer]
SET [FirstName] = @FirstName, [LastName] = @LastName, [City] = @City, [State] = @State
WHERE [CustomerId] = @CustomerId" OnDeleted="CustomerSqlDataSource_Deleted">
<DeleteParameters>
<asp:Parameter Name="CustomerId" Type="Int32" />
</DeleteParameters>
<InsertParameters>
<asp:Parameter Name="FirstName" Type="String" />
<asp:Parameter Name="LastName" Type="String" />
<asp:Parameter Name="City" Type="String" />
<asp:Parameter Name="State" Type="String" />
</InsertParameters>
<UpdateParameters>
<asp:Parameter Name="FirstName" Type="String" />
<asp:Parameter Name="LastName" Type="String" />
<asp:Parameter Name="City" Type="String" />
<asp:Parameter Name="State" Type="String" />
<asp:Parameter Name="CustomerId" Type="Int32" />
</UpdateParameters>
</asp:SqlDataSource>
</p>
其背后的代码不起作用:
protected void CustomerSqlDataSource_Deleted(object sender, SqlDataSourceStatusEventArgs e)
{
if (e.ExceptionHandled == false)
{
e.Command.Cancel();
DeleteLabel.Visible = true;
DeleteLabel.Text = "This Customer cannot be deleted";
}
}
============================================================================================================================================================================================================================================
在美国东部标准时间上午 11:41 编辑以包含整个错误。 虽然,我明白问题是什么,我只是想在此错误显示之前捕获此错误并将其带回页面上的标签,并让标签显示"无法删除客户">
============================================================================================================================================================================================================================================"/"应用程序中的服务器错误。
DELETE 语句与 REFERENCE 约束"FK_SalesOrder_Customer"冲突。冲突发生在数据库"ITP236-清单"中,表"dbo.销售订单",列"客户 ID"。该语句已终止。
说明:执行当前 Web 请求期间发生未经处理的异常。请查看堆栈跟踪,了解有关错误及其在代码中起源位置的详细信息。
异常详细信息:System.Data.SqlClient.SqlException:DELETE 语句与 REFERENCE 约束"FK_SalesOrder_Customer"冲突。冲突发生在数据库"ITP236-清单"中,表"dbo.销售订单",列"客户 ID"。该语句已终止。
源错误:
在执行当前 Web 请求期间生成了未经处理的异常。可以使用下面的异常堆栈跟踪来识别有关异常来源和位置的信息。
堆栈跟踪:
[SqlException (0x80131904(:DELETE 语句与 REFERENCE 约束"FK_SalesOrder_Customer"冲突。冲突发生在数据库"ITP236-清单"中,表"dbo.销售订单",列"客户 ID"。该声明已终止。 System.Data.SqlClient.SqlConnection.OnError(SqlException exception, Boolean breakConnection, Action 1 wrapCloseInAction) +1767866
System.Data.SqlClient.SqlInternalConnection.OnError(SqlException exception, Boolean breakConnection, Action
1 wrapCloseInAction( +5352418 System.Data.SqlClient.TdsParser.ThrowExceptionAndWarning(TdsParserStateObject stateObj, Boolean callerHasConnectionLock, Boolean asyncClose( +244 System.Data.SqlClient.TdsParser.TryRun(RunBehavior runBehavior, SqlCommand cmdHandler, SqlDataReader dataStream, BulkCopySimpleResultSet bulkCopyHandler, TdsParserStateObject stateObj, Boolean& dataReady( +1691 System.Data.SqlClient.SqlCommand.FinishExecuteReader(SqlDataReader ds, RunBehavior runBehavior, String resetOptionsString( +269 System.Data.SqlClient.SqlCommand.RunExecuteReaderTds(CommandBehavior cmdBehavior, RunBehavior runBehavior, Boolean returnStream, Boolean async, Int32 timeout, Task& task, Boolean asyncWrite, SqlDataReader ds( +1406 System.Data.SqlClient.SqlCommand.RunExecuteReader(CommandBehavior cmdBehavior, RunBehavior runBehavior, Boolean returnStream, String method, TaskCompletionSource 1 completion, Int32 timeout, Task& task, Boolean asyncWrite) +177
System.Data.SqlClient.SqlCommand.InternalExecuteNonQuery(TaskCompletionSource
1 completion, String methodName, Boolean sendToPipe, Int32 timeout, Boolean asyncWrite( +205 System.Data.SqlClient.SqlCommand.ExecuteNonQuery(( +160 System.Web.UI.WebControls.SqlDataSourceView.ExecuteDbCommand(DbCommand command, DataSourceOperation operation( +380 System.Web.UI.WebControls.SqlDataSourceView.ExecuteDelete(IDictionary keys, IDictionary oldValues( +568 System.Web.UI.DataSourceView.Delete(IDictionary keys, IDictionary oldValues, DataSourceViewOperationCallback callback( +84 System.Web.UI.WebControls.GridView.HandleDelete(GridViewRow row, Int32 rowIndex( +930 System.Web.UI.WebControls.GridView.HandleEvent(EventArgs e, Boolean causesValidation, String validationGroup( +974 System.Web.UI.WebControls.GridView.RaisePostBackEvent(String eventArgument( +205 System.Web.UI.WebControls.GridView.System.Web.UI.IPostBackEventHandler.RaisePostBackEvent(String eventArgument( +13 System.Web.UI.Page.RaisePostBackEvent(IPostBackEventHandler sourceControl, String eventArgument( +13 System.Web.UI.Page.RaisePostBackEvent(NameValueCollection postData( +9671830 System.Web.UI.Page.ProcessRequestMain(Boolean includeStagesBeforeAsyncPoint, Boolean includeStagesAfterAsyncPoint( +1724
;ASP.NET 版本:4.0.30319.34237
您收到的错误是由于违反了外键约束。Customer
表的主键在某个其他表的外键约束中引用。您无法删除客户,因为其他一些表取决于客户。
例如,如果有一个Orders
表,其中有一个CustomerId
列引用您尝试删除的客户,该怎么办?客户订购产品,因此没有客户就无法存在订单。在这种情况下,请尝试更改 DELETE 语句:
DELETE FROM [Customer] WHERE [CustomerId] = @CustomerId
AND NOT EXISTS (SELECT * FROM [Orders] AS o WHERE o.[CustomerId]=@CustomerId)
这将防止删除有订单的客户。您可以在 Deleted
事件中按如下方式处理此问题:
protected void CustomerSqlDataSource_Deleted(object sender, SqlDataSourceStatusEventArgs e)
{
if (e.AffectedRows == 0)
{
DeleteLabel.Visible = true;
DeleteLabel.Text = "This Customer cannot be deleted because it has orders";
}
}
您可以通过选中e.Exception != null
而不是e.ExceptionHandled == false
来处理异常。
protected void CustomerSqlDataSource_Deleted(object sender, SqlDataSourceStatusEventArgs e)
{
try {
if (e.ExceptionHandled == false)
{
e.Command.Cancel();
DeleteLabel.Visible = true;
DeleteLabel.Text = "This Customer cannot be deleted";
}
catch {
// do your thing here when error occurs
}
}