|
系列文章導(dǎo)航:
一步一步學(xué)Linq to sql(一):預(yù)備知識(shí)
一步一步學(xué)Linq to sql(二):DataContext與實(shí)體
一步一步學(xué)Linq to sql(四):查詢(xún)句法
一步一步學(xué)Linq to sql(五):存儲(chǔ)過(guò)程
一步一步學(xué)Linq to sql(七):并發(fā)與事務(wù)
一步一步學(xué)Linq to sql(八):繼承與關(guān)系
一步一步學(xué)Linq to sql(九):其它補(bǔ)充
一步一步學(xué)Linq to sql(十):分層構(gòu)架的例子
項(xiàng)目介紹
這節(jié)將要把《一步一步學(xué)Linq to sql(三):增刪改》中留言簿的例子修改為使用WCF的多層構(gòu)架。我們將會(huì)建立以下項(xiàng)目:
l A,網(wǎng)站項(xiàng)目 WebSite:留言簿表現(xiàn)層
l B,類(lèi)庫(kù)項(xiàng)目 Contract:定義數(shù)據(jù)訪問(wèn)服務(wù)的契約
l C,類(lèi)庫(kù)項(xiàng)目 Service:定義數(shù)據(jù)訪問(wèn)服務(wù)
l D,類(lèi)庫(kù)項(xiàng)目Entity:留言簿實(shí)體
l E,控制臺(tái)項(xiàng)目Host:承載數(shù)據(jù)訪問(wèn)服務(wù)
項(xiàng)目之間的引用如下:
l A引用B和D;
l B引用D和System.ServiceModel程序集
l C引用B、D、System.ServiceModel以及System.Data.Linq程序集
l D引用System.Data.Linq程序集
l E引用C和System.ServiceModel程序集
生成映射文件和實(shí)體
打開(kāi)VS2008命令行提示,執(zhí)行以下命令:
sqlmetal /conn:server=xxx;database=GuestBook;uid=xxx;pwd=xxx /map:c:/guestbook.map /code:c:/guestbook.cs /serialization:Unidirectional |
注意到,這里我們使用了serialization開(kāi)關(guān),告知sqlmetal在生成實(shí)體的時(shí)候自動(dòng)把它們標(biāo)記為WCF數(shù)據(jù)對(duì)象。生成結(jié)束后把C:/GUESTBOOK.CS添加到Entity項(xiàng)目中。
系列文章導(dǎo)航:
一步一步學(xué)Linq to sql(一):預(yù)備知識(shí)
一步一步學(xué)Linq to sql(二):DataContext與實(shí)體
一步一步學(xué)Linq to sql(四):查詢(xún)句法
一步一步學(xué)Linq to sql(五):存儲(chǔ)過(guò)程
一步一步學(xué)Linq to sql(七):并發(fā)與事務(wù)
一步一步學(xué)Linq to sql(八):繼承與關(guān)系
一步一步學(xué)Linq to sql(九):其它補(bǔ)充
一步一步學(xué)Linq to sql(十):分層構(gòu)架的例子
編寫(xiě)數(shù)據(jù)訪問(wèn)服務(wù)
首先我們可以定義出留言簿數(shù)據(jù)訪問(wèn)服務(wù)的契約(接口),把如下的代碼保存為IDataAccess.cs放在Contract類(lèi)庫(kù)項(xiàng)目中:
using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.ServiceModel;
namespace Contract { [ServiceContract] public interface IDataAccess { [OperationContract] void SendMessage(TbGuestBook gb);
[OperationContract] List<TbGuestBook> GetData();
[OperationContract] void DeleteMessage(string ID);
[OperationContract] void SendReply(TbGuestBook gb); } } |
在這里定義了四個(gè)方法:
l 創(chuàng)建留言
l 獲取所有留言
l 刪除留言
l 管理員發(fā)表回復(fù)
然后,我們來(lái)實(shí)現(xiàn)這個(gè)契約,把如下代碼保存為DataAccess.cs放在Service類(lèi)庫(kù)項(xiàng)目中:
using System; using System.Collections.Generic; using System.Linq; using System.Text; using Contract; using System.Data.Linq.Mapping; using System.IO; using System.ServiceModel;
namespace Service { [ServiceBehavior(IncludeExceptionDetailInFaults = true)] public class DataAccess : IDataAccess { GuestBook ctx;
public DataAccess() { XmlMappingSource xms = XmlMappingSource.FromXml(File.ReadAllText("c://guestbook.map")); ctx = new GuestBook("server=srv-devdbhost;database=GuestBook;uid=sa;pwd=Abcd1234", xms); ctx.Log = Console.Out; }
public void SendMessage(TbGuestBook gb) { ctx.TbGuestBook.Add(gb); ctx.SubmitChanges(); }
public List<TbGuestBook> GetData() { var query = from gb in ctx.TbGuestBook orderby gb.PostTime descending select gb; return query.ToList();
}
public void DeleteMessage(string ID) { TbGuestBook gb = ctx.TbGuestBook.Single(message => message.ID == new Guid(ID)); ctx.TbGuestBook.Remove(gb); ctx.SubmitChanges(); }
public void SendReply(TbGuestBook gb) { //ctx.ExecuteCommand("update tbGuestBook set reply={0},isreplied=1 where ID={1}", gb.Reply, gb.ID); TbGuestBook record = ctx.TbGuestBook.Single(message => message.ID == gb.ID); record.IsReplied = true; record.Reply = gb.Reply; ctx.SubmitChanges(); } } } |
這里需要注意幾點(diǎn):
l 我們把DataContext的操作在控制臺(tái)輸出
l 在進(jìn)行發(fā)表回復(fù)(更新操作)的時(shí)候,注釋的代碼和沒(méi)有注釋的代碼雖然都能完成更新操作,但是前者更合理,因?yàn)楹笳邥?huì)先進(jìn)行SELECT再進(jìn)行UPDATE
系列文章導(dǎo)航:
一步一步學(xué)Linq to sql(一):預(yù)備知識(shí)
一步一步學(xué)Linq to sql(二):DataContext與實(shí)體
一步一步學(xué)Linq to sql(四):查詢(xún)句法
一步一步學(xué)Linq to sql(五):存儲(chǔ)過(guò)程
一步一步學(xué)Linq to sql(七):并發(fā)與事務(wù)
一步一步學(xué)Linq to sql(八):繼承與關(guān)系
一步一步學(xué)Linq to sql(九):其它補(bǔ)充
一步一步學(xué)Linq to sql(十):分層構(gòu)架的例子
WCF服務(wù)端與客戶(hù)端
打開(kāi)Host項(xiàng)目中的Program.cs,使用下面的代碼來(lái)實(shí)現(xiàn)WCF的服務(wù)端:
using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.ServiceModel; using Service; using Contract;
namespace Host { class Program { static void Main(string[] args) {
Uri uri = new Uri("NET.tcp://localhost:8080/DataAccessService"); using (ServiceHost sh = new ServiceHost(typeof(DataAccess), uri)) { NETTcpBinding ctb = new NETTcpBinding(); sh.AddServiceEndpoint(typeof(IDataAccess), ctb, string.Empty); sh.Opened += delegate { Console.WriteLine("服務(wù)已經(jīng)啟動(dòng)"); }; sh.Open(); Console.ReadLine(); } } } } |
在WebSite項(xiàng)目中的App_Code文件夾下創(chuàng)建一個(gè)用戶(hù)調(diào)用服務(wù)的類(lèi),GetService.cs:
using System; using System.Data; using System.Configuration; using System.Linq; using System.Web; using System.Web.Security; using System.Web.UI; using System.Web.UI.WebControls; using System.Web.UI.WebControls.WebParts; using System.Web.UI.HtmlControls; using System.Xml.Linq; using Contract; using System.ServiceModel.Description; using System.ServiceModel;
public class GetService { public static IDataAccess GetDataAccessService() { ServiceEndpoint sep = new ServiceEndpoint(ContractDescription.GetContract(typeof(IDataAccess)), new NETTcpBinding(), new EndpointAddress("NET.tcp://localhost:8080/DataAccessService"));
ChannelFactory<IDataAccess> cf = new ChannelFactory<IDataAccess>(sep);
return cf.CreateChannel(); } } |
系列文章導(dǎo)航:
一步一步學(xué)Linq to sql(一):預(yù)備知識(shí)
一步一步學(xué)Linq to sql(二):DataContext與實(shí)體
一步一步學(xué)Linq to sql(四):查詢(xún)句法
一步一步學(xué)Linq to sql(五):存儲(chǔ)過(guò)程
一步一步學(xué)Linq to sql(七):并發(fā)與事務(wù)
一步一步學(xué)Linq to sql(八):繼承與關(guān)系
一步一步學(xué)Linq to sql(九):其它補(bǔ)充
一步一步學(xué)Linq to sql(十):分層構(gòu)架的例子
調(diào)用服務(wù)
最后,就可以調(diào)用數(shù)據(jù)訪問(wèn)服務(wù)來(lái)進(jìn)行留言、回復(fù)、刪除留言等操作了。頁(yè)面的代碼不再貼了,大家可以看第三篇或者下載源代碼。我們把Default.cs修改成如下:
public partial class _Default : System.Web.UI.Page { 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.IsReplied = false; gb.PostTime = DateTime.Now; gb.UserName = tb_UserName.Text; gb.Message = tb_Message.Text; GetService.GetDataAccessService().SendMessage(gb); SetBind(); } private void SetBind() { rpt_Message.DataSource = GetService.GetDataAccessService().GetData(); rpt_Message.DataBind(); } } |
Admin.cs代碼修改成如下:
public partial class Admin : System.Web.UI.Page { protected void Page_Load(object sender, EventArgs e) { if (!IsPostBack) { SetBind(); } }
private void SetBind() { rpt_Message.DataSource = GetService.GetDataAccessService().GetData(); rpt_Message.DataBind(); } protected void rpt_Message_ItemCommand(object source, RepeaterCommandEventArgs e) { if (e.CommandName == "DeleteMessage") { GetService.GetDataAccessService().DeleteMessage(e.CommandArgument.ToString()); SetBind(); } if (e.CommandName == "SendReply") { TbGuestBook gb = new TbGuestBook(); gb.ID = new Guid(e.CommandArgument.ToString()); gb.Reply = ((TextBox)e.Item.FindControl("tb_Reply")).Text; GetService.GetDataAccessService().SendReply(gb); SetBind(); } } } |
就這樣實(shí)現(xiàn)了一個(gè)多層構(gòu)架的留言簿程序。對(duì)于WCF的一些內(nèi)容本文不多作解釋了。點(diǎn)擊這里下載本篇代碼。
如果您覺(jué)得這個(gè)例子太簡(jiǎn)單,還可以在這里下載一個(gè)Linq/WCF/MVC結(jié)合使用更復(fù)雜的例子,此例的目的主要演示一個(gè)框架,實(shí)現(xiàn)不完整。
一步一步學(xué)Linq to sql到這里就結(jié)束了,看到這里應(yīng)該已經(jīng)算師父領(lǐng)進(jìn)門(mén)了,后續(xù)的提高還要靠大家自己去琢磨。
it知識(shí)庫(kù):一步一步學(xué)Linq to sql(十):分層構(gòu)架的例子,轉(zhuǎn)載需保留來(lái)源!
鄭重聲明:本文版權(quán)歸原作者所有,轉(zhuǎn)載文章僅為傳播更多信息之目的,如作者信息標(biāo)記有誤,請(qǐng)第一時(shí)間聯(lián)系我們修改或刪除,多謝。