如何建立一個 CRUD 列表畫面 (影片)
CRUD(新增、查詢、修改、刪除)是一個軟體系統中最常見的功能,在實作上,它包含2個操作畫面,一是資料列表畫面(以下稱列表畫面),用來輸入查詢條件和顯示查詢結果;另一個是編輯畫面,用來新增或是修改資料。 在這裡我們要介紹如何建立一個清單畫面。
以資料庫文件系統裡面的 [欄位維護] 功能為例,它的列表畫面如下:
畫面上方是查詢欄位,下方是查詢結果;在這裡,我們使用 jQuery Datatables 來顯示查詢結果,包含畫面上的分頁元件。清單畫面運行時的邏輯為:
1.收集使用者輸入的查詢條件
2.轉換成 SQL 字串,送交資料庫查詢
3.將查詢結果交給 jQuery Datatables 呈現在畫面上
在上面的項目中,步驟1的處理程式為 wwwroot/js/base/_code.js,步驟2則由 Base/Services/CrudRead.cs 來處理,這兩個檔案都是屬於軟體積木的一部分,程式員需要自行處理的有3項工作:製作查詢畫面、撰寫 sql 內容、定義查詢欄位的比對方式。在 ASP.NET Core MVC 的架構下,程式員的3項工作與 [欄位維護] 功能的清單畫面的相關檔案的對應關係如下:
Controllers/ColumnController.cs:controller
Services/ColumnRead.cs:設定 sql 內容和欄位定義
Views/Column/Read.cshtml:查詢畫面
wwwroot/js/view/Column.js:呼叫 jQuery Datatables
ColumnController.cs
這個檔案的清單畫面相關功能有2個函數,內容都十分簡單,其中 Read 的用來傳回清單畫面,GetPage 用來傳回查詢的結果,程式碼如下:
//顯示清單畫面
public ActionResult Read()
{
//讀取專案欄位(下拉式)來源資料
ViewBag.Projects = _Code.GetProjects();
return View();
}
//傳回查詢結果
[HttpPost]
public ContentResult GetPage(DtDto dt)
{
return Content(new ColumnRead().GetPage(dt).ToString(), _Web.AppJson, Encoding.UTF8);
}
ColumnRead.cs
在以下的程式碼中,上方的 SQL 內容為標準的語法,你可以先在 SSMS 做驗證;下方的3個欄位,則對應到查詢畫面的輸入欄位。
private ReadDto model = new ReadDto()
{
ReadSql = @"
Select
p.Code as ProjectCode, t.Code as TableCode,
c.Id, c.Code, c.Name,
c.Status, c.DataType
From dbo.[Column] c
inner join dbo.[Table] t on t.Id=c.TableId
inner join dbo.Project p on p.Id=t.ProjectId
Order by p.Id, t.Id, c.Sort
",
TableAs = "c",
Items = new [] {
new QitemDto { Fid = "ProjectId", Col = "t.ProjectId" },
new QitemDto { Fid = "TableCode", Col = "t.Code", Op = ItemOpEstr.Like },
new QitemDto { Fid = "Code", Op = ItemOpEstr.Like },
},
};
Read.cshtml
以下是查詢畫面的主要程式內容,我們使用 .Net Core View Component 來撰寫3個查詢欄位,他們看起來跟一般的 HTML 語法有些不一樣;下方的查詢結果,我們使用 table 元素,來搭配 jQuery Datatables。
<!-- 查詢畫面 -->
<div id="divRead">
<!-- 查詢條件 -->
<form id='rform' class='xg-form'>
<div class="row">
@await Component.InvokeAsync("XiSelect", new { title = "專案", fid = "ProjectId", rows = (List<IdStrDto>)ViewBag.Projects, inRow = true })
@await Component.InvokeAsync("XgFindTbar")
</div>
@await Component.InvokeAsync("XiText", new { title = "資料表", fid = "TableCode", maxLen = 30 })
@await Component.InvokeAsync("XiText", new { title = "欄位", fid = "Code", maxLen = 30 })
</form>
<!-- 查詢結果 -->
<table id="table1" class="table table-bordered xg-table" cellspacing="0">
<thead>
<tr>
<th>專案</th>
<th>資料表</th>
<th>欄位</th>
<th>欄位名稱</th>
<th>資料型態</th>
<th width='80px'>維護功能</th>
<th width='60px'>資料狀態</th>
</tr>
</thead>
<tbody></tbody>
</table>
</div>
Column.js
這個檔案內容用來處理 jQuery Datatables 的欄位顯示。
var _me = {
init: function () {
//設定 jQuery Datatables 組態
var config = {
dom: _crud.dtDom,
columns: [
{ data: 'ProjectCode' },
{ data: 'TableCode' },
{ data: 'Code' },
{ data: 'Name' },
{ data: 'DataType' },
{ data: '_CrudFun' },
{ data: 'Status' },
],
columnDefs: [
_crud.dtColConfig,
{ targets: [5], render: function (data, type, full, meta) {
return _crud.dtCrudFun(full.Id, full.Name, true, true, false);
}},
{ targets: [6], render: function (data, type, full, meta) {
return _crud.dtStatusName(data);
}},
],
};
//初始化 crud
_crud.init(config);
},
}; //class
完成上面4個檔案後,[欄位維護] 的列表畫面功能就已經完成了,它的難度應該是大部分人都可以勝任,你可以在 Visual Studio 啟動它並且查詢資料。另外,當列表畫面執行查詢功能時,系統會將 SQL 內容記錄在 _log 目錄底下,方便你在開發的過程中隨時檢查,以下是檔案的部分內容:
14:08:33(0);
Select Count(*) as _count From dbo.[Column] c
inner join dbo.[Table] t on t.Id=c.TableId
inner join dbo.Project p on p.Id=t.ProjectId Where t.ProjectId = @ProjectId And t.Code like @TableCode(Db,Column%)
14:08:33(0);
select
p.Code as ProjectCode, t.Code as TableCode,
c.Id, c.Code, c.Name,
c.Status, c.DataType From dbo.[Column] c
inner join dbo.[Table] t on t.Id=c.TableId
inner join dbo.Project p on p.Id=t.ProjectId Where t.ProjectId = @ProjectId And t.Code like @TableCode Order by p.Id, t.Id, c.Sort
offset 0 rows fetch next 10 rows only
(Db,Column%)