从依赖于另一个表的表中删除实体

时间:2009-09-27 20:23:55

标签: c# asp.net sql-server sql-server-2005

我有2个表机组和机器。 MachineGroups有列:

  • MachinegroupID
  • MachineGroupName
  • MachineGroupDesc

And Machines有专栏:

  • MachineGroupID(FK)
  • 机号
  • 计算机名
  • Machinedesc

现在我要删除一个机器组,但不删除那些有机器的机器组。 因此,如果有机器,它应该给出错误消息....说你不能删除。

这就是我想要做的......

<asp:GridView ID="GridView1" runat="server" AllowSorting="True"
    AutoGenerateColumns="False" CellPadding="1" CellSpacing="2"
    DataSourceID="SqlDataSource1" ForeColor="#333333" GridLines="None"
     Width="100%" ondatabound="GridView1_DataBound1"
    onrowdatabound="GridView1_RowDataBound1">
    <RowStyle BackColor="#D0D8E8" ForeColor="#333333" Height="35px" />
    <Columns>
        <asp:BoundField DataField="MachineGroupID" HeaderText="MachineGroupID" 
            InsertVisible="False" ReadOnly="True" SortExpression="MachineGroupID" 
            Visible="False" />
        <asp:BoundField DataField="MachineGroupName" HeaderText="MachineGroupName" 
            SortExpression="MachineGroupName" />
        <asp:BoundField DataField="MachineGroupDesc" HeaderText="MachineGroupDesc" 
            SortExpression="MachineGroupDesc" />
        <asp:BoundField DataField="TimeAdded" HeaderText="TimeAdded" 
            SortExpression="TimeAdded" />
        <asp:TemplateField HeaderText="CanBeDeleted" SortExpression="CanBeDeleted" 
            Visible="False">
            <EditItemTemplate>
                <asp:CheckBox ID="CheckBox1" runat="server"
                    Checked='<%# Bind("CanBeDeleted") %>' />
            </EditItemTemplate>
            <ItemTemplate>
                <asp:CheckBox ID="CheckBox1" runat="server"
                    Checked='<%# Bind("CanBeDeleted") %>' Enabled="false" />
            </ItemTemplate>
        </asp:TemplateField>
        <asp:BoundField DataField="No. of PCs" HeaderText="No. of PCs" ReadOnly="True"
            SortExpression="No. of PCs" />
        <asp:TemplateField ShowHeader="False">
            <ItemTemplate>
                <asp:LinkButton ID="LinkButton1" runat="server" CausesValidation="False"
                    CommandName="Delete" Text="Delete"></asp:LinkButton>
            </ItemTemplate>
        </asp:TemplateField>
    </Columns>
    <FooterStyle BackColor="#5D7B9D" Font-Bold="True" ForeColor="White" />
    <PagerStyle BackColor="#284775" ForeColor="White" HorizontalAlign="Center" />
    <SelectedRowStyle BackColor="#E2DED6" Font-Bold="True" ForeColor="#333333" />
    <HeaderStyle BackColor="#4F81BD" Font-Bold="True" ForeColor="White"
        Height="30px" />
    <EditRowStyle BackColor="#999999" />
    <AlternatingRowStyle BackColor="#E9EDF4" ForeColor="#284775" />
</asp:GridView>


<asp:SqlDataSource ID="SqlDataSource1" runat="server"         ConnectionString="<%$ ConnectionStrings:SumooHAgentDBConnectionString %>" 
    SelectCommand="SELECT MachineGroups.MachineGroupID, MachineGroups.MachineGroupName, MachineGroups.MachineGroupDesc, MachineGroups.TimeAdded, MachineGroups.CanBeDeleted, COUNT(Machines.MachineName) AS 'No. of PCs' FROM MachineGroups FULL OUTER JOIN Machines ON Machines.MachineGroupID = MachineGroups.MachineGroupID GROUP BY MachineGroups.MachineGroupID, MachineGroups.MachineGroupName, MachineGroups.MachineGroupDesc, MachineGroups.TimeAdded, MachineGroups.CanBeDeleted" 
    DeleteCommand="DELETE FROM MachineGroups WHERE (MachineGroupID = @original_MachineGroupID) AND (MachineGroupName = @original_MachineGroupName) AND (MachineGroupDesc = @original_MachineGroupDesc) AND (CanBeDeleted = @original_CanBeDeleted) AND (TimeAdded = @original_TimeAdded)">
    <DeleteParameters>
        <asp:Parameter Name="original_MachineGroupID" />
        <asp:Parameter Name="original_MachineGroupName" />
        <asp:Parameter Name="original_MachineGroupDesc" />
        <asp:Parameter Name="original_CanBeDeleted" />
        <asp:Parameter Name="original_TimeAdded" />
    </DeleteParameters>
</asp:SqlDataSource>

请建议做什么..

5 个答案:

答案 0 :(得分:1)

处理您的GridView的 RowDeleting RowDeleted 事件。在RowDeleting中,您可以运行Palo建议的查询,并运行查询以检查该组是否为空:

protected void GridView1_RowDeleting(object sender, GridViewDeleteEventArgs e)
{
    int mgid = e.Keys["MachineGroupId"];
    if (!GroupIsEmpty(mgid))
    {
        e.Cancel = true;
    }
}

在'RowDeleted'中,您可以检查是否存在异常,因为当您的约束正常工作时应该存在,并且您没有如上所述取消删除:

protected void GridView1_RowDeleted(object sender, GridViewDeletedEventArgs e)
{
    if ((e.Exception != null) && (e.ExceptionHandled))
    {
        errorLabel.Text = "Machine group could not be deleted.  This is probably because machines still exist for the group.";
    }
}

答案 1 :(得分:0)

您需要先删除子行。所以可能有2个删除程序。类似的东西:

DELETE 
FROM machines 
WHERE
MachineGroupID = @IN_MachineGroupID

DELETE 
FROM machinesGroups 
WHERE
MachineGroupID = @IN_MachineGroupID

在我看来,使用DataSet和DataAdapter使这更容易。查看ADO.Net断开层。

我注意到你想抛出一个错误 - 你的页面背后有代码吗?

你需要做

Try
{
   call your delete;
}
catch(Exception ex)
{
   throw (ex.Messgae)
}

你可以更准确地解决你所寻找的错误,但是你明白了。

答案 2 :(得分:0)

在旧的SQL中,您需要做的就是删除MachineGroups中未在Machines表中列为MachineGroupID的条目:

DELETE FROM MachineGroups
 WHERE MachineGroupID NOT IN (SELECT DISTINCT MachineGroupID FROM Machines)

如何将其转换为ASP / XML是任何人的猜测。

答案 3 :(得分:0)

我假设您在两个表MachinesMachineGroups之间存在外键关系,对吗? (基于MachineGroupID)

如果该FK关系未指定ON DELETE CASCADE选项,那么您可以做的是

  • 尝试删除计算机组
  • 捕获可能发生的任何异常,表明由于现有子行而无法删除
  • 向用户显示该消息(或其用户友好的“翻译”)

但是,如果该FK关系确实指定了ON DELETE CASCADE选项,那么在删除该计算机组之前,您必须首先检查以确保给定MachineGroupID没有子行。

马克

答案 4 :(得分:0)

在具有该组ID的计算机上运行简单计数:

select count(id) from Machines where MachineGroupId == groupIdToDelete;

如果有计数,您可以显示错误消息或其他任何内容。

如果没有计数,请继续删除。