取消"删除" event if" DELETE语句与REFERENCE约束冲突"

时间:2014-12-12 14:16:43

标签: c# asp.net entity-framework events

我使用的是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编辑,包含整个错误。虽然,我明白问题是什么, 我只是试图在显示之前捕获此错误并将其恢复 页面上的标签,标签上写着&#34;客户无法删除&#34;

=============================================== =============================== &#39; /&#39;中的服务器错误应用

DELETE语句与REFERENCE约束冲突&#34; FK_SalesOrder_Customer&#34;。冲突发生在数据库&#34; ITP236-Inventory&#34;,table&#34; dbo.SalesOrder&#34;,column&#39; CustomerId&#39;中。 声明已经终止。

描述:执行当前Web请求期间发生了未处理的异常。请查看堆栈跟踪以获取有关错误及其源自代码的位置的更多信息。

异常详细信息:System.Data.SqlClient.SqlException:DELETE语句与REFERENCE约束冲突&#34; FK_SalesOrder_Customer&#34;。冲突发生在数据库&#34; ITP236-Inventory&#34;,table&#34; dbo.SalesOrder&#34;,column&#39; CustomerId&#39;中。 声明已经终止。

来源错误:

在执行当前Web请求期间生成了未处理的异常。可以使用下面的异常堆栈跟踪来识别有关异常的起源和位置的信息。

堆栈追踪:

[SqlException(0x80131904):DELETE语句与REFERENCE约束冲突&#34; FK_SalesOrder_Customer&#34;。冲突发生在数据库&#34; ITP236-Inventory&#34;,table&#34; dbo.SalesOrder&#34;,column&#39; CustomerId&#39;中。 该语句已终止。]    System.Data.SqlClient.SqlConnection.OnError(SqlException异常,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&amp; 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&amp; 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命令,DataSourceOperation操作)+380    System.Web.UI.WebControls.SqlDataSourceView.ExecuteDelete(IDictionary keys,IDictionary oldValues)+568    System.Web.UI.DataSourceView.Delete(IDictionary keys,IDictionary oldValues,DataSourceViewOperationCallback回调)+84    System.Web.UI.WebControls.GridView.HandleDelete(GridViewRow row,Int32 rowIndex)+930    System.Web.UI.WebControls.GridView.HandleEvent(EventArgs e,Boolean causeValidation,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

版本信息:Microsoft .NET Framework版本:4.0.30319; ASP.NET版本:4.0.30319.34237

2 个答案:

答案 0 :(得分:1)

您收到的错误是由于违反了外键约束。 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来处理异常。

答案 1 :(得分:0)

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
     }
}