首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
您现在的位置: 程式碼之家 >> 編程語言 >  >> .NET 網頁程式設計 >> ASP.NET 基礎 >> ASP.NET 基礎

ASP.NET DataList 刪除功能完整實作:單筆刪除與批次刪除

     編輯:ASP.NET 基礎

DataList 控制項特色

DataList 是輕量級資料繫結控制項,支援自訂版面(Template)、內建 `ItemCommand` 事件處理按鈕命令、`DataKeyField` 存取主鍵值,適合簡單清單操作。

一、前端 .aspx 完整標記

<%@ Page Language="C#" AutoEventWireup="true" CodeBehind="DataListDelete.aspx.cs" Inherits="Demo.DataListDelete" %>
<!DOCTYPE html>
<html><head><title>DataList 刪除示範</title>
<script type="text/javascript">
    // 全選/反選
    function CheckAll(chk) {
        var checkboxes = document.getElementsByTagName('input');
        for (var i = 0; i < checkboxes.length; i++) {
            if (checkboxes[i].type === 'checkbox' && checkboxes[i].id !== chk.id) {
                checkboxes[i].checked = chk.checked;
            }
        }
    }
</script>
</head><body>
<form id="form1" runat="server">
<fieldset style="width:600px;">
<legend>DataList 刪除操作(支援批次刪除)</legend>

<asp:DataList ID="dlUsers" runat="server" DataKeyField="id" OnItemCommand="dlUsers_ItemCommand">
    <HeaderTemplate>
        <table border="1" cellpadding="0" cellspacing="0" style="width:100%; border-collapse:collapse;">
        <tr style="background:#f0f0f0;">
            <th width="50"><input type="checkbox" onclick="CheckAll(this)" title="全選/反選" /></th>
            <th>編號</th><th>暱稱</th><th>簽名</th><th>操作</th>
        </tr>
    </HeaderTemplate>

    <ItemTemplate>
        <tr>
            <td align="center"><asp:CheckBox ID="chkItem" runat="server" /></td>
            <td><asp:Label ID="lblId" runat="server" Text='<%# Eval("id") %>' /></td>
            <td><asp:Label ID="lblName" runat="server" Text='<%# Eval("bg_name") %>' /></td>
            <td><asp:Label ID="lblSign" runat="server" Text='<%# Eval("bg_p_autograph") %>' /></td>
            <td align="center">
                <asp:Button ID="btnDel" runat="server" Text="刪除" CommandName="delete" 
                    OnClientClick="return confirm('確定刪除此筆資料?');" CssClass="btn-del" />
            </td>
        </tr>
    </ItemTemplate>

    <FooterTemplate>
        <tr>
            <td colspan="5" align="center">
                <asp:Button ID="btnBatchDel" runat="server" Text="批次刪除選取" CommandName="batchdelete" 
                    OnClientClick="return confirm('確定批次刪除選取項目?');" CssClass="btn-batch" />
            </td>
        </tr>
        </table>
    </FooterTemplate>
</asp:DataList>
</fieldset></form></body></html>

二、後端 .aspx.cs 完整邏輯

using System;
using System.Data;
using System.Data.SqlClient;
using System.Configuration;
using System.Web.UI.WebControls;

namespace Demo
{
    public partial class DataListDelete : System.Web.UI.Page
    {
        private readonly string _connStr = ConfigurationManager.ConnectionStrings["connStr"].ConnectionString;

        protected void Page_Load(object sender, EventArgs e)
        {
            if (!IsPostBack) BindDataList();
        }

        private void BindDataList()
        {
            using (var conn = new SqlConnection(_connStr))
            using (var da = new SqlDataAdapter("SELECT id, bg_name, bg_p_autograph FROM bg_spatial", conn))
            {
                var dt = new DataTable();
                da.Fill(dt);
                dlUsers.DataSource = dt;
                dlUsers.DataBind();
            }
        }

        protected void dlUsers_ItemCommand(object source, DataListCommandEventArgs e)
        {
            switch (e.CommandName)
            {
                case "delete": // 單筆刪除
                    DeleteSingle(e);
                    break;
                case "batchdelete": // 批次刪除
                    DeleteBatch();
                    break;
            }
        }

        private void DeleteSingle(DataListCommandEventArgs e)
        {
            int id = Convert.ToInt32(dlUsers.DataKeys[e.Item.ItemIndex]);
            ExecuteDelete(id, "單筆刪除");
        }

        private void DeleteBatch()
        {
            int successCount = 0;
            foreach (DataListItem item in dlUsers.Items)
            {
                if (item.ItemType == ListItemType.Item || item.ItemType == ListItemType.AlternatingItem)
                {
                    var chk = (CheckBox)item.FindControl("chkItem");
                    if (chk != null && chk.Checked)
                    {
                        int id = Convert.ToInt32(dlUsers.DataKeys[item.ItemIndex]);
                        if (ExecuteDelete(id, "批次刪除", false)) successCount++;
                    }
                }
            }
            ShowMessage($"批次刪除完成,成功 {successCount} 筆。");
            BindDataList();
        }

        private bool ExecuteDelete(int id, string actionName, bool showMsg = true)
        {
            try
            {
                using (var conn = new SqlConnection(_connStr))
                using (var cmd = new SqlCommand("DELETE FROM bg_spatial WHERE id = @id", conn))
                {
                    cmd.Parameters.AddWithValue("@id", id);
                    conn.Open();
                    int rows = cmd.ExecuteNonQuery();
                    if (showMsg) ShowMessage(rows > 0 ? $"{actionName} 成功!" : $"{actionName} 失敗,資料不存在。");
                    return rows > 0;
                }
            }
            catch (Exception ex)
            {
                if (showMsg) ShowMessage($"{actionName} 發生錯誤:{ex.Message}");
                return false;
            }
        }

        private void ShowMessage(string msg)
        {
            ClientScript.RegisterStartupScript(GetType(), "msg", $"alert('{msg.Replace("'", "\\'")}');", true);
        }
    }
}

關鍵技術點解析

技術點說明
DataKeyField指定主鍵欄位 ``,避免在畫面顯示 ID 或藏在 HiddenField
DataKeys 集合`dlUsers.DataKeys[e.Item.ItemIndex]` 取得對應項目主鍵,型別安全
CommandNameButton/LinkButton/ImageButton 設定 `CommandName`,統一在 `ItemCommand` 事件分派
FindControl`item.FindControl("chkItem")` 取得 Template 內控制項實例
ItemType 判斷只處理 `Item` / `AlternatingItem`,略過 Header/Footer/Separator
參數化查詢`@id` 參數防止 SQL Injection,效能較好(計畫快取)
Using 區塊確保連線/命令正確 Dispose,避免連線洩漏

進階優化建議

  • 交易包裝批次刪除:多筆刪除建議用 `TransactionScope` 或 `SqlTransaction` 確保原子性。
  • IN 子句單次刪除:收集所有 ID → `DELETE FROM table WHERE id IN (...)` 單次往返,效能優於迴圈。
  • 軟刪除:加 `IsDeleted` 欄位,避免資料遺失,查詢加 `WHERE IsDeleted=0`。
  • 前端增強:jQuery 統一綁定確認對話框、AJAX 非同步刪除、刪除後局部更新。
  • 分頁/排序:DataList 原生不支援,需自行實作或改用 GridView/ListView。

常見錯誤與除錯

現象原因解決
DataKeys 取值為 null/錯誤未設定 DataKeyField 或 ItemIndex 錯誤檢查 DataKeyField、確認 e.Item.ItemIndex
批次刪除未勾選也刪除ItemType 未過濾 Header/Footer加 `if (item.ItemType == ListItemType.Item || ...)`
刪除後畫面未更新未重新 BindDataList()刪除成功後呼叫 BindDataList()
SQL 例外:外鍵衝突關聯資料存在先刪子表、或設定 CASCADE DELETE、或軟刪除
  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved