程序師世界是廣大編程愛好者互助、分享、學習的平台,程序師世界有你更精彩!
首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫知識
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
 程式師世界 >> 編程語言 >> .NET網頁編程 >> 關於.NET >> 學Linq to sql(十):分層構架的例子

學Linq to sql(十):分層構架的例子

編輯:關於.NET

項目介紹

這節將要把《學Linq to sql (三):增刪改》中留言簿的例子修改為使用WCF的多層構架。我們將會建立以下項目:

l A,網站項目 WebSite:留言簿表現層

l B,類庫項目 Contract:定義數據訪問服務的契約

l C,類庫項目 Service:定義數據訪問服務

l D,類庫項目Entity:留言簿實體

l E,控制台項目Host:承載數據訪問服務

項目之間的引用如下:

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程序集

生成映射文件和實體

打開VS2008命令行提示,執行以下命令:

sqlmetal /conn:server=xxx;database=GuestBook;uid=xxx;pwd=xxx /map:c:\guestbook.map /code:c:\guestbook.cs /serialization:Unidirectional

注意到,這裡我們使用了serialization開關,告知sqlmetal在生成實體的時候自動把它們標記為WCF數據對象。生成結束後把C:\GUESTBOOK.CS添加到Entity項目中。

編寫數據訪問服務

首先我們可以定義出留言簿數據訪問服務的契約(接口),把如下的代碼保存為IDataAccess.cs放在Contract類庫項目中:

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);

    }

}

在這裡定義了四個方法:

l 創建留言

l 獲取所有留言

l 刪除留言

l 管理員發表回復

然後,我們來實現這個契約,把如下代碼保存為DataAccess.cs放在Service類庫項目中:

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();

        }

    }

}

這裡需要注意幾點:

l 我們把DataContext的操作在控制台輸出

l 在進行發表回復(更新操作)的時候,注釋的代碼和沒有注釋的代碼雖然都能完成更新操作,但是前者更合理,因為後者會先進行SELECT再進行UPDATE

WCF服務端與客戶端

打開Host項目中的Program.cs,使用下面的代碼來實現WCF的服務端:

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("服務已經啟動"); };

                sh.Open();

                Console.ReadLine();

            }

        }

    }

}

在WebSite項目中的App_Code文件夾下創建一個用戶調用服務的類,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 ();

    }

}

調用服務

最後,就可以調用數據訪問服務來進行留言、回復、刪除留言等操作了。頁面的代碼不再貼了,大家可以看第三篇或者下載源代碼。我們把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();

        }

    }

}

就這樣實現了一個多層構架的留言簿程序。對於WCF的一些內容本文不多作解釋了。點擊這裡下載本篇代碼。

如果您覺得這個例子太簡單,還可以在這裡下載一個Linq/WCF/MVC結合使用更復雜的例子,此例的目的主要演示一個框架,實現不完整。

一步一步學Linq to sql到這裡就結束了,看到這裡應該已經算師父領進門了,後續的提高還要靠大家自己去琢磨。

  1. 上一頁:
  2. 下一頁:
Copyright © 程式師世界 All Rights Reserved