延續前兩篇「預備知識」與「DataContext 與實體」,本文將透過一個完整的 ASP.NET 留言板專案,示範如何利用 LINQ to SQL 輕鬆實現 Create、Read、Update、Delete 四大核心操作,並展示自動產生的 SQL 語句,讓你體會「像操作記憶體物件一樣操作資料庫」的開發體驗。
| 欄位名 | 型別 | 允許 Null | 說明 |
|---|---|---|---|
| ID | uniqueidentifier | 否 | 主鍵 |
| UserName | varchar(50) | 否 | 留言者 |
| PostTime | datetime | 否 | 留言時間 |
| Message | varchar(400) | 是 | 內容 |
| IsReplied | bit | 否 | 是否回覆 |
| Reply | varchar(400) | 是 | 管理員回覆 |
GuestBook.dbmltbGuestBook 拖曳至設計介面,Ctrl+S 儲存GuestBookDataContext 及 tbGuestBook 實體類別
public partial class _Default : System.Web.UI.Page
{
GuestBookDataContext ctx = new GuestBookDataContext(
"server=xxx;database=GuestBook;uid=xxx;pwd=xxx");
protected void Page_Load(object sender, EventArgs e)
{
if (!IsPostBack) SetBind();
}
protected void btn_SendMessage_Click(object sender, EventArgs e)
{
var gb = new tbGuestBook
{
ID = Guid.NewGuid(),
UserName = tb_UserName.Text,
Message = tb_Message.Text,
IsReplied = false,
PostTime = DateTime.Now
};
ctx.tbGuestBooks.Add(gb); // 加入追蹤
ctx.SubmitChanges(); // 送出 INSERT
SetBind();
}
private void SetBind()
{
rpt_Message.DataSource = from gb in ctx.tbGuestBooks
orderby gb.PostTime descending
select gb;
rpt_Message.DataBind();
}
}

protected void rpt_Message_ItemCommand(object source, RepeaterCommandEventArgs e)
{
var id = new Guid(e.CommandArgument.ToString());
var gb = ctx.tbGuestBooks.Single(b => b.ID == id);
if (e.CommandName == "DeleteMessage")
{
ctx.tbGuestBooks.Remove(gb); // 刪除追蹤
ctx.SubmitChanges(); // 送出 DELETE
}
else if (e.CommandName == "SendReply")
{
gb.Reply = ((TextBox)e.Item.FindControl("tb_Reply")).Text;
gb.IsReplied = true; // 修改屬性
ctx.SubmitChanges(); // 送出 UPDATE
}
SetBind();
}

UPDATE [dbo].[tbGuestBook]
SET [IsReplied] = @p4, [Reply] = @p5
WHERE ([ID] = @p0) AND ([UserName] = @p1) AND ([PostTime] = @p2)
AND ([Message] = @p3) AND (NOT ([IsReplied] = 1)) AND ([Reply] IS NULL)
LINQ to SQL 預設採用 樂觀平行存取,WHERE 條件包含所有原始欄位值,確保資料未被他人異動。
DELETE FROM [dbo].[tbGuestBook]
WHERE ([ID] = @p0) AND ([UserName] = @p1) AND ([PostTime] = @p2)
AND ([Message] = @p3) AND (NOT ([IsReplied] = 1)) AND ([Reply] = @p4)
var sw = new StreamWriter(Server.MapPath("log.txt"), true);
ctx.Log = sw; // 所有 SQL 寫入 log.txt
// ... 執行操作 ...
sw.Close();
輸出範例:
SELECT ... FROM [tbGuestBook] WHERE ...
-- @p0: Input Guid ...
-- Context: SqlProvider(Sql2005) Model : AttributedMetaModel Build: 3.5.20706.1
下一篇將系統介紹「查詢語法」進階篇,敬請期待!