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

ASP.NET 三層架構新聞管理系統設計與 ADO.NET 斷開式資料模型實戰

     編輯:關於ASP.NET

系統架構:標準三層模式

層級技術實作職責
UI 層 (表現層)ASP.NET Web Forms (.aspx + CodeBehind)使用者互動、資料呈現、輸入驗證、頁面流程控制
BLL (商務邏輯層)VB.NET/C# Class Library業務規則驗證、工作流程協調、資料轉換、呼叫 DAL
DAL (資料存取層)ADO.NET (SqlClient/OleDb) + SQL ServerCRUD 操作、預存程序呼叫、連線管理、交易控制

三層架構圖

ASP.NET 對比傳統 ASP 的四大優勢

  1. 編譯型執行:首次請求編譯為 IL,後續直接執行,無需每次解析腳本,效能大幅提升。
  2. 豐富資料繫結控制項:GridView、DetailsView、FormView、ListView 內建分頁、排序、編輯、範本,無需手寫迴圈輸出 HTML。
  3. 應用程式即時更新:部署新組件無需停止 IIS/網站,舊請求完成後平滑切換新版本,檔案永不鎖定。
  4. Code-Behind 分離:UI 標記 (.aspx) 與邏輯 (.aspx.vb/.cs) 分離,支援設計師/開發者並行、版本控制、單元測試。

ADO.NET 斷開式資料架構核心

連線模式 vs 斷開模式

  • 傳統連線模式:開啟連線 → 執行命令 → 讀取 DataReader → 關閉連線。連線佔用期間無法服務其他請求,不適合 Web 高併發。
  • ADO.NET 斷開模式:
    1. SqlDataAdapter.Fill(DataSet):開啟連線 → 讀取資料 → 關閉連線 (連線池歸還)。
    2. 資料存在記憶體 DataSet (內含 DataTable、DataRelation、Constraint),**完全脫離資料庫**。
    3. UI 對 DataSet 操作 (繫結、篩選、排序、編輯) 無資料庫連線開銷。
    4. 批次更新:DataAdapter.Update(DataSet) 重新開啟連線,以交易方式寫回變更。

DataSet:記憶體中關聯式資料快取

  • 支援多資料表、關聯 (DataRelation)、約束 (PK/FK/Unique)。
  • 不感知資料來源 (SQL Server、Oracle、XML、CSV 皆可填充)。
  • 序列化為 XML 便於跨層傳遞、Web Service 回傳、離線快取。

新聞管理系統核心功能實作範例

DAL:新聞 CRUD (採用參數化查詢防 SQL Injection)

Public Class NewsDAL
    Private ReadOnly _connStr As String = ConfigurationManager.ConnectionStrings("NewsDB").ConnectionString
    
    Public Function GetNewsList() As DataTable
        Using conn As New SqlConnection(_connStr)
            Dim sql As String = "SELECT NewsID, Title, ClassID, PublishDate, IsTop FROM News ORDER BY IsTop DESC, PublishDate DESC"
            Dim da As New SqlDataAdapter(sql, conn)
            Dim dt As New DataTable()
            da.Fill(dt)
            Return dt
        End Using
    End Function
    
    Public Function GetNewsById(newsID As Integer) As DataRow
        Using conn As New SqlConnection(_connStr)
            Dim sql As String = "SELECT * FROM News WHERE NewsID = @NewsID"
            Dim cmd As New SqlCommand(sql, conn)
            cmd.Parameters.AddWithValue("@NewsID", newsID)
            Dim da As New SqlDataAdapter(cmd)
            Dim dt As New DataTable()
            da.Fill(dt)
            Return If(dt.Rows.Count > 0, dt.Rows(0), Nothing)
        End Using
    End Function
    
    Public Function InsertNews(title As String, classID As Integer, content As String, isTop As Boolean) As Integer
        Using conn As New SqlConnection(_connStr)
            Dim sql As String = "INSERT INTO News (Title, ClassID, Content, PublishDate, IsTop) VALUES (@Title, @ClassID, @Content, GETDATE(), @IsTop); SELECT SCOPE_IDENTITY();"
            Dim cmd As New SqlCommand(sql, conn)
            cmd.Parameters.AddWithValue("@Title", title)
            cmd.Parameters.AddWithValue("@ClassID", classID)
            cmd.Parameters.AddWithValue("@Content", content)
            cmd.Parameters.AddWithValue("@IsTop", isTop)
            conn.Open()
            Return Convert.ToInt32(cmd.ExecuteScalar())
        End Using
    End Function
    
    Public Function UpdateNews(newsID As Integer, title As String, classID As Integer, content As String, isTop As Boolean) As Boolean
        Using conn As New SqlConnection(_connStr)
            Dim sql As String = "UPDATE News SET Title=@Title, ClassID=@ClassID, Content=@Content, IsTop=@IsTop WHERE NewsID=@NewsID"
            Dim cmd As New SqlCommand(sql, conn)
            cmd.Parameters.AddWithValue("@NewsID", newsID)
            cmd.Parameters.AddWithValue("@Title", title)
            cmd.Parameters.AddWithValue("@ClassID", classID)
            cmd.Parameters.AddWithValue("@Content", content)
            cmd.Parameters.AddWithValue("@IsTop", isTop)
            conn.Open()
            Return cmd.ExecuteNonQuery() > 0
        End Using
    End Function
    
    Public Function DeleteNews(newsID As Integer) As Boolean
        Using conn As New SqlConnection(_connStr)
            Dim sql As String = "DELETE FROM News WHERE NewsID = @NewsID"
            Dim cmd As New SqlCommand(sql, conn)
            cmd.Parameters.AddWithValue("@NewsID", newsID)
            conn.Open()
            Return cmd.ExecuteNonQuery() > 0
        End Using
    End Function
End Class

BLL:業務規則封裝 (如標題唯一性、分類存在性驗證)

Public Class NewsBLL
    Private ReadOnly _dal As New NewsDAL()
    
    Public Function AddNews(title As String, classID As Integer, content As String, isTop As Boolean) As Integer
        ' 業務規則:標題不重複
        If _dal.ExistsTitle(title) Then Throw New ArgumentException("標題已存在")
        ' 業務規則:分類必須存在
        If Not New CategoryDAL().Exists(classID) Then Throw New ArgumentException("分類不存在")
        Return _dal.InsertNews(title, classID, content, isTop)
    End Function
    
    Public Function GetPagedNews(pageIndex As Integer, pageSize As Integer, ByRef totalCount As Integer) As DataTable
        Return _dal.GetPagedNews(pageIndex, pageSize, totalCount)
    End Function
End Class

UI:GridView 列表 + ObjectDataSource 繫結

<asp:GridView ID="gvNews" runat="server" DataSourceID="odsNews" 
    AllowPaging="true" PageSize="15" AllowSorting="true"
    DataKeyNames="NewsID" AutoGenerateColumns="False">
    <Columns>
        <asp:BoundField DataField="NewsID" HeaderText="ID" SortExpression="NewsID" />
        <asp:BoundField DataField="Title" HeaderText="標題" SortExpression="Title" />
        <asp:TemplateField HeaderText="分類">
            <ItemTemplate>
                <%# Eval("ClassName") %> <!-- 需 DAL JOIN 取得 -->
            </ItemTemplate>
        </TemplateField>
        <asp:BoundField DataField="PublishDate" HeaderText="發布日期" DataFormatString="{0:yyyy/MM/dd}" SortExpression="PublishDate" />
        <asp:CheckBoxField DataField="IsTop" HeaderText="置頂" SortExpression="IsTop" />
        <asp:CommandField ShowEditButton="true" ShowDeleteButton="true" />
    </Columns>
</asp:GridView>

<asp:ObjectDataSource ID="odsNews" runat="server" 
    TypeName="NewsBLL" SelectMethod="GetPagedNews" 
    DeleteMethod="DeleteNews" UpdateMethod="UpdateNews"
    OnSelecting="odsNews_Selecting">
    <SelectParameters>
        <asp:Parameter Name="pageIndex" Type="Int32" />
        <asp:Parameter Name="pageSize" Type="Int32" />
    </SelectParameters>
</asp:ObjectDataSource>
Protected Sub odsNews_Selecting(sender As Object, e As ObjectDataSourceSelectingEventArgs)
    e.InputParameters("pageIndex") = gvNews.PageIndex
    e.InputParameters("pageSize") = gvNews.PageSize
End Sub

效能優化關鍵點

  • 分頁查詢下推資料庫:使用 ROW_NUMBER() OVER (ORDER BY ...) 或 OFFSET/FETCH (SQL 2012+) 只取當頁資料,避免全表撈入記憶體。
  • 分類主檔快取:Cache.Insert("Categories", GetAllCategories(), ..., 1小時),UI 繫結時查字典不查 DB。
  • 連線池:連線字串啟用 Pooling=true; Min Pool Size=5; Max Pool Size=100 (預設即開啟)。
  • 非同步資料存取:.NET 4.5+ 使用 async/await + ExecuteReaderAsync 釋放執行緒提升併發。

結語

ASP.NET 三層架構配合 ADO.NET 斷開式資料模型,構建了高效能、可維護、可擴展的新聞管理系統基石。關鍵在於:DAL 專注資料存取細節 (參數化、連線池、分頁下推)、BLL 封裝業務不變量、UI 層善用資料繫結控制項與 ObjectDataSource 減少樣板代碼。理解斷開式架構「連線極短、資料在記憶體、批次更新」的精髓,才能發揮 ADO.NET 最大效能優勢。

  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved