=x= 🌵 NEWS 前台 List 頁面後端功能製作。
📌 由於新聞列表切換會重覆讀取資料庫,因此 SQL 與語法先使用 CTE 暫存表取出今天日期前的資料做為資料暫存表,再用這個暫存表的資料依分頁是第幾頁取出每頁的每筆資料。
protected void Page_Load(object sender, EventArgs e)
{
    if (!IsPostBack) {
        loadNewsList();
    }
}
private void loadNewsList()
{
    //取得目前的時間,只顯示日期前的新聞
    DateTime nowTime = DateTime.Now;
    string nowDate = nowTime.ToString("yyyy-MM-dd");
    //1.連線資料庫
    SqlConnection connection = new SqlConnection(WebConfigurationManager.ConnectionStrings["TayanaYachtConnectionString"].ConnectionString);
    //2.建立判斷網址是否有傳值邏輯 (網址傳值功能已於製作控制項時已完成)
    int page = 1; //預設為第1頁
    //判斷網址後有無參數
    //也可用String.IsNullOrWhiteSpace
    if (!String.IsNullOrEmpty(Request.QueryString["page"])) {
        page = Convert.ToInt32(Request.QueryString["page"]);
    }
    //3.設定頁面參數屬性
    //設定控制項參數: 一頁幾筆資料
    WebUserControl_Page.limit = 5;
    //設定控制項參數: 作用頁面完整網頁名稱
    WebUserControl_Page.targetPage = "new_list.aspx";
    //4.建立計算分頁資料顯示邏輯 (每一頁是從第幾筆開始到第幾筆結束)
    //計算每個分頁的第幾筆到第幾筆
    var floor = (page - 1) * WebUserControl_Page.limit + 1; //每頁的第一筆
    var ceiling = page * WebUserControl_Page.limit; //每頁的最末筆
    //5.建立計算資料筆數的 SQL 語法
    //算出我們要秀的資料數
    string sql_countTotal = "SELECT COUNT(id) FROM News WHERE dateTitle <= @nowDate";
    SqlCommand commandForTotal = new SqlCommand(sql_countTotal, connection);
    commandForTotal.Parameters.AddWithValue("@nowDate", nowDate); //只秀當天及之前的資料
    //6.將取得的資料數設定給參數 count
    connection.Open();
    //用 ExecuteScalar() 來算數量
    int count = Convert.ToInt32(commandForTotal.ExecuteScalar());
    connection.Close();
    //7.將取得的資料筆數設定給頁面參數屬性
    //設定控制項參數: 總共幾筆資料
    WebUserControl_Page.totalItems = count;
    //8.使用 showPageControls() 渲染至網頁 (方法於製作控制項時已完成)
    //渲染分頁控制項
    WebUserControl_Page.showPageControls();
    //9.將原始資料表的 SQL 語法使用 CTE 暫存表改寫,並使用 ROW_NUMBER() 函式製作資料項流水號 rowindex
    // SQL 用 CTE 暫存表 + ROW_NUMBER 去生出我的流水號 rowindex 後以流水號為條件來查詢暫存表
    // 排序先用 isTop 後用 dateTitle 產生 TOP News 置頂效果
    string sql = $"WITH temp AS (SELECT ROW_NUMBER() OVER (ORDER BY isTop DESC, dateTitle DESC) AS rowindex, * FROM News WHERE dateTitle <= @nowDate) SELECT * FROM temp WHERE rowindex >= {floor} AND rowindex <= {ceiling}";
    SqlCommand command = new SqlCommand(sql, connection);
    command.Parameters.AddWithValue("@nowDate", nowDate);
    //10.取得每頁的新聞列表資料製作成 HTML 內容
    connection.Open();
    StringBuilder newListHtml = new StringBuilder();
    SqlDataReader reader = command.ExecuteReader();
    while (reader.Read()) {
        string idStr = reader["id"].ToString();
        DateTime dateTimeTitle = DateTime.Parse(reader["dateTitle"].ToString());
        string dateTitleStr = dateTimeTitle.ToString("yyyy/M/d");
        string headlineStr = reader["headline"].ToString();
        string summaryStr = reader["summary"].ToString();
        string thumbnailPathStr = reader["thumbnailPath"].ToString();
        string guidStr = reader["guid"].ToString();
        string isTopStr = reader["isTop"].ToString();
        string displayStr = "none";
        if (isTopStr.Equals("True")) {
            displayStr = "inline-block";
        }
        newListHtml.Append($"<li><div class='list01'><ul><li><div class='news01'>" +
            $"<img src='images/new_top01.png' alt='""' style='display: {displayStr};position: absolute;z-index: 5;'/>" +
            $"<div class='news02p1' style='margin: 0px;border-width: 0px;padding: 0px;' ><p>" +
            $"<img id='thumbnail_Image{idStr}' src='upload/Images/{thumbnailPathStr}' style='border-width: 0px;position: absolute;z-index: 1;' width='161px' height='121px' />" +
            $"</p></div></li><li><span>{dateTitleStr}</span><br />" +
            $"<a href='new_view.aspx?id={guidStr}'>{headlineStr} </a></li><br />" +
            $"<li>{summaryStr} </li></ul></div></li>");
    }
    connection.Close();
    //渲染新聞列表
    newList.Text = newListHtml.ToString();
}
🌵 縮圖 Top 焦點新聞標籤為參考遊艇首頁 HTML 後發現,於是在列表頁也一併加入。
👀 SQL CTE 語法參考 : [SQL] 使用 CTE 遞迴查詢 (PostgreSQL / MSSQL)
👀 SQL CTE 介紹參考 : SQL Server 暫存表(@ # ##)與CTE (Common Table Expressions)
👀 SQL ROW_NUMBER() 語法參考 : SQL Server 暫存表(@ # ##)與CTE (Common Table Expressions)
📢 今天最難的地方大概是 SQL 的 CTE 語法,因為裡面還加了 ROW_NUMBER() 及 ORDER BY 語法,可能要多花一點時間去理解,類似你有一個大的資料櫃裡面有很多資料夾,只要有新的業務成立就會放到資料櫃裡最前面,你打算抽出已結案的部分拿出來,將裡面有貼上 VIP 標籤的先整理到前面,然後分別依結案日期排列,排完之後再一一貼上從數字 1 開始的貼紙,最後分給來幫你輸入到電腦做電子化的人,資料夾從最前面開始拿,每個人發 5 個直到分完,這些幫輸入資料的人就是分頁,抽出來的就是暫存要分掉的資料數,語法有包含括號的子查詢,加上條件的變數,看起來很恐怖,可以慢慢拆解再去理解。