• 一步一步学Linq to sql(十):分层构架的例子


       

    项目介绍

     

           这节将要把《一步一步学Linq to sql(三):增删改》中留言簿的例子修改为使用WCF的多层构架。我们将会建立以下项目:

    l         A,网站项目 WebSite:留言簿表现层

    l         B,类库项目 Contract:定义数据访问服务的契约

    l         C,类库项目 Service:定义数据访问服务

    l         D,类库项目Entity:留言簿实体

    l         E,控制台项目Host:承载数据访问服务

    项目之间的引用如下:

    l         A引用BD

    l         B引用DSystem.ServiceModel程序集

    l         C引用BDSystem.ServiceModel以及System.Data.Linq程序集

    l         D引用System.Data.Linq程序集

    l         E引用CSystem.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到这里就结束了,看到这里应该已经算师父领进门了,后续的提高还要靠大家自己去琢磨。

  • 相关阅读:
    HDU4911——归并排序——Inversion
    HDU5400——Arithmetic Sequence
    HDU5396——区间DP+排列组合——Expression
    DFS(连通块) ZOJ 2743 Bubble Shooter
    Codeforces Round #345 (Div. 2)
    Codeforces Round #344 (Div. 2)
    8VC Venture Cup 2016
    Manthan, Codefest 16
    DP(记忆化搜索) + AC自动机 LA 4126 Password Suspects
    全排列 UVA 11525 Permutation
  • 原文地址:https://www.cnblogs.com/lovecherry/p/878907.html
Copyright © 2020-2023  润新知