示例數據庫
字段名 |
字段類型 |
允許空 |
字段說明 |
ID |
uniqueidentifier |
|
表主鍵字段 |
UserName |
varchar(50) |
|
留言用戶名 |
PostTime |
datetime |
|
留言時間 |
Message |
varchar(400) |
√ |
留言內容 |
IsReplied |
bit |
|
留言是否回覆 |
Reply |
varchar(400) |
√ |
留言管理員回覆 |
在數據庫中創建一個名爲 GuestBook 的數據庫,在裏面創建一個 tbGuestBook 的表,結構如上表。
生成實體類
右鍵點擊網站項目,選擇添加新項,然後選擇“ Linq to sql Classes ”,命名爲 GuestBook 。然後打開 App_Code 裏面的 GuestBook.dbml 。設計視圖上的文字提示你可以從服務器資源管理器或者攻擊箱拖動項到設計界面上來創建實體類。
那麼,我們就在服務器資源管理器中創建一個指向 GuestBook 數據庫的數據連接,然後把 tbGuestBook 表拖動到 GuestBook.dbml 的設計視圖上,按 CTRL+S 保存。打開 GuestBook.designer.cs 可以發現系統自動創建了 GuestBook 數據庫中 tbGuestBook 表的映射,如下圖:
簡易留言簿
現在,我們就可以使用 Linq to sql 完成簡易留言簿了。實現以下功能:
l 發表留言(增)
l 查看留言(查)
l 管理員回覆留言(改)
l 管理員刪除留言(刪除)
首先,創建一個 Default.aspx ,在頁面上加入一些控件:
< div > 姓名 < asp : TextBox ID ="tb_UserName" runat ="server"></ asp : TextBox >< br /> < br /> 留言 < asp : TextBox ID ="tb_Message" runat ="server" Height ="100px" TextMode ="MultiLine" Width ="300px"></ asp : TextBox >< br /> < br /> < asp : Button ID ="btn_SendMessage" runat ="server" Text =" 發表留言 " OnClick ="btn_SendMessage_Click" />< br /> < br /> < asp : Repeater ID ="rpt_Message" runat ="server"> < ItemTemplate > < table width ="600px" style =" border :solid 1px #666666 ; font-size :10pt ; background-color :#f0f0f0"> < tr > < td align ="left" width ="400px"> <% # Eval("Message" )%> </ td > < td align ="right" width ="200px"> <% # Eval("PostTime" )%> - <% # Eval("UserName" )%> </ td > </ tr > < tr > < td colspan ="2" align ="right"> < hr width ="300px" /> 管理員回覆: <% # Eval("IsReplied" ).ToString() == "False" ? " 暫無 " : Eval("Reply" )%> </ td > </ tr > </ table > < br /> </ ItemTemplate > </ asp : Repeater > </ div > |
你可能很難想象,使用 Linq to sql 進行數據訪問會是這麼簡單,後臺代碼:
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) { tbGuestBook gb = new tbGuestBook (); gb.ID = Guid .NewGuid(); gb.UserName = tb_UserName.Text; gb.Message = tb_Message.Text; gb.IsReplied = false ; gb.PostTime = DateTime .Now; ctx.tbGuestBooks.Add(gb); ctx.SubmitChanges(); SetBind(); } private void SetBind() { rpt_Message.DataSource = from gb in ctx.tbGuestBooks orderby gb.PostTime descending select gb; rpt_Message.DataBind(); } } |
前面創建 Linq to sql Classes 的時候我們輸入名字 GuestBook ,系統就爲我們自動創建了 GuestBookDataContext (你也可以在 GuestBook.Designer.cs 中找到類定義)。在綁定的時候我們使用查詢句法查詢留言表中所有留言,按照發表時間倒序(天哪?這是數據訪問嗎?好像僅僅定義了一句 SQL 啊)。在發表留言按鈕中,我們爲一個 tbGuestBook 賦值,然後把它加入留言表,再提交更改,就這樣完成了記錄的插入。
運行效果如下圖:
然後,再創建一個 Admin.aspx ,前臺代碼如下:
< div > < asp : Repeater ID ="rpt_Message" runat ="server" OnItemCommand ="rpt_Message_ItemCommand"> < ItemTemplate > < table width ="600px" style =" border :solid 1px #666666 ; font-size :10pt ; background-color :#f0f0f0"> < tr > < td align ="left" width ="400px"> <% # Eval("Message")%> </ td > < td align ="right" width ="200px"> <% # Eval("PostTime")%> - <% # Eval("UserName")%> </ td > </ tr > < tr > < td colspan ="2" align ="right"> < hr width ="300px" /> < asp : Button ID ="btn_DeleteMessage" runat ="server" Text =" 刪除留言 " CommandName ="DeleteMessage" CommandArgument =' <% # Eval("ID")%> '/> 管理員回覆: < asp : TextBox runat ="server" ID ="tb_Reply" TextMode ="MultiLine" Width ="300px" Text =' <% # Eval("Reply")%> '/> < asp : Button ID ="btn_SendReply" runat ="server" Text =" 發表回覆 " CommandName ="SendReply" CommandArgument =' <% # Eval("ID")%> '/> </ td > </ tr > </ table > < br /> </ ItemTemplate > </ asp : Repeater > </ div > |
後臺代碼:
public partial class Admin : 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(); } }
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) { if (e.CommandName == "DeleteMessage" ) { StreamWriter sw = new StreamWriter (Server.MapPath("log.txt" ), true ); ctx.Log = sw; tbGuestBook gb = ctx.tbGuestBooks.Single(b => b.ID == new Guid (e.CommandArgument.ToString())); ctx.tbGuestBooks.Remove(gb); ctx.SubmitChanges(); SetBind(); sw.Close(); } if (e.CommandName == "SendReply" ) { StreamWriter sw = new StreamWriter (Server.MapPath("log.txt" ), true ); ctx.Log = sw; tbGuestBook gb = ctx.tbGuestBooks.Single(b => b.ID == new Guid (e.CommandArgument.ToString())); gb.Reply = ((TextBox )e.Item.FindControl("tb_Reply" )).Text; gb.IsReplied = true ; ctx.SubmitChanges(); SetBind(); sw.Close(); } } } |
運行效果如下圖:
在這裏,我們通過 Single 方法獲取一條記錄,也就是一個 tbGuestBook 實例,更新了一些屬性後保存也就完成了改這個操作。刪除操作更簡單,只需要從表中移除對象。你是不是覺得好像不是在操作數據庫,像在操作內存中的對象。
由於寫了日誌,看看改和刪操作會是怎麼樣的 SQL ?
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)
-- @p0: Input Guid (Size = 0; Prec = 0; Scale = 0) [00000000-0000-0000-0000-000000000000]
-- @p1: Input String (Size = 4; Prec = 0; Scale = 0) [ghgh]
-- @p2: Input DateTime (Size = 0; Prec = 0; Scale = 0) [2007-8-16 10:20:09]
-- @p3: Input String (Size = 3; Prec = 0; Scale = 0) [ghj]
-- @p4: Input Boolean (Size = 0; Prec = 0; Scale = 0) [True]
-- @p5: Input String (Size = 3; Prec = 0; Scale = 0) [qqq]
-- Context: SqlProvider(Sql2005) Model: AttributedMetaModel Build: 3.5.20706.1
DELETE FROM [dbo].[tbGuestBook] WHERE ([ID] = @p0) AND ([UserName] = @p1) AND ([PostTime] = @p2) AND ([Message] = @p3) AND (NOT ([IsReplied] = 1)) AND ([Reply] = @p4)
-- @p0: Input Guid (Size = 0; Prec = 0; Scale = 0) [158ec941-13ff-4093-bd8b-9fceae152171]
-- @p1: Input String (Size = 2; Prec = 0; Scale = 0) [44]
-- @p2: Input DateTime (Size = 0; Prec = 0; Scale = 0) [2007-8-16 9:56:19]
-- @p3: Input String (Size = 2; Prec = 0; Scale = 0) [44]
-- @p4: Input String (Size = 3; Prec = 0; Scale = 0) [222]
-- Context: SqlProvider(Sql2005) Model: AttributedMetaModel Build: 3.5.20706.1