• 一步一步学Linq to sql(十):多层架构MVC WCF Linq


    前言

    本次主要是使用WCF的多层架构。我们将建立以下项目:

     A,MVC网站项目 MvcOperation:留言簿表现层
     B,类库项目 Contract:定义数据访问服务的契约
     C,类库项目 Service:定义数据访问服务
     D,类库项目Entity:留言簿实体
     E,控制台项目Host:承载数据访问服务

    项目之间的引用如下:
     A引用B和D;
     B引用D和System.ServiceModel程序集
     C引用B、D、System.ServiceModel以及System.Data.Linq程序集
     D引用System.Data.Linq程序集
     E引用C和System.ServiceModel程序集
    生成映射文件和实体
    打开VS2010命令行提示,执行以下命令:

    sqlmetal /conn:server=.;database=GuestBook;uid=sa;pwd=saa /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
        {
            /// <summary>
            /// 添加  or 修改
            /// </summary>
            /// <param name="gb"></param>
            [OperationContract]
            void SendMessage(TbGuestBook gb);
    
            /// <summary>
            /// 获取所有信息
            /// </summary>
            /// <returns></returns>
            [OperationContract]
            List<TbGuestBook> GetData();
    
            /// <summary>
            /// 删除
            /// </summary>
            /// <param name="ID"></param>
            [OperationContract]
            void DeleteMessage(string ID);
    
    
            /// <summary>
            /// 获取一条记录
            /// </summary>
            /// <param name="ID"></param>
            /// <returns></returns>
            [OperationContract]
            TbGuestBook GetDataID(string ID);
    
        }
    }

    然后,我们来实现这个契约,把如下代码保存为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=.;database=GuestBook;uid=sa;pwd=saa", xms);
                ctx.Log = Console.Out;
            }
    
    
            public void SendMessage(TbGuestBook gb)
            {
                TbGuestBook tb =null;
                tb = GetDataID(gb.ID.ToString());
                if (tb != null)
                {
                    tb.Message = gb.Message;
                    tb.Reply = gb.Reply;
                    tb.PostTime = gb.PostTime;
                    tb.UserName = gb.UserName;
                    ctx.SubmitChanges();
                }
                else
                {
                    ctx.TbGuestBook.InsertOnSubmit(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.DeleteOnSubmit(gb);
                ctx.SubmitChanges();
            }
    
            public TbGuestBook GetDataID(string ID)
            {
                TbGuestBook record = ctx.TbGuestBook.SingleOrDefault(message => message.ID.ToString() ==ID);
                return record;
            }
        }
    }

    WCF服务端与客户端

     打开Host项目中的Program.cs,使用下面的代码来实现WCF的服务端:

    using System;
    using System.Collections.Generic;
    using System.Linq;
    using System.Text;
    using Service;
    using System.ServiceModel;
    using Contract;
    
    namespace Host
    {
        class Program
        {
            static void Main(string[] args)
            {
                Uri uri = new Uri("net.tcp://localhost:880/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();
                }
    
            }
        }
    }

    在MvcOption项目中添加一个Helper文件夹下创建一个用户调用服务的类,ServerHelper.cs:

    using System;
    using System.Collections.Generic;
    using System.Linq;
    using System.Web;
    using System.ServiceModel.Description;
    using System.ServiceModel;
    using Contract;
    
    namespace MvcOperation.Helper
    {
        public class ServerHelper
        {
            public static IDataAccess GetDataAccessService()
            {
    
                ServiceEndpoint sep = new ServiceEndpoint(ContractDescription.GetContract(typeof(IDataAccess)),
                    new NetTcpBinding(),
                    new EndpointAddress("net.tcp://localhost:880/DataAccessService"));
                ChannelFactory<IDataAccess> cf = new ChannelFactory<IDataAccess>(sep);
                return cf.CreateChannel();
            }
    
        }
    }

    最后对控制器中的代码进行修正如下:

    using System;
    using System.Collections.Generic;
    using System.Linq;
    using System.Web;
    using System.Web.Mvc;
    using System.Configuration;
    using System.IO;
    using MvcOperation.Helper;
    
    namespace MvcOperation.Controllers
    {
        public class HomeController : Controller
        {
            public ActionResult Index()
            {
                ViewBag.Message = "欢迎使用 ASP.NET MVC!";
                //List<tbGuestBook> list = (from gb in ctx.tbGuestBook
                //                         orderby gb.PostTime descending 
                //                         select gb).ToList();
    
                return View("Index", ServerHelper.GetDataAccessService().GetData());
            }
    
            public ActionResult About()
            {
                return View();
            }
    
            public ActionResult AddBook()
            {
                return View();
            }
    
            public ActionResult DelBook(string id)
            {
                //tbGuestBook gb = ctx.tbGuestBook.Single(b => b.ID == new Guid(id));
                //ctx.tbGuestBook.DeleteOnSubmit(gb);
                //ctx.SubmitChanges();
                ServerHelper.GetDataAccessService().DeleteMessage(id);
                return Index();
            }
    
            public ActionResult UpdateBook(string id)
            {
                TbGuestBook gb = ServerHelper.GetDataAccessService().GetDataID(id);
                return View("AddBook",gb);
    
            }
    
            public ActionResult SaveBook(TbGuestBook tb)
            {
                TbGuestBook gb = null;
                if (tb.ID.ToString() != "00000000-0000-0000-0000-000000000000")
                {
                    gb = ServerHelper.GetDataAccessService().GetDataID(tb.ID.ToString());
                    gb.PostTime = DateTime.Now;
                    gb.UserName = tb.UserName;
                    gb.Message = tb.Message;
                    ServerHelper.GetDataAccessService().SendMessage(gb);
                    return Index();
                }
                else
                {
                    tb.ID = Guid.NewGuid();
                    tb.IsReplied = false;
                    tb.PostTime = DateTime.Now;
                    ServerHelper.GetDataAccessService().SendMessage(tb);
                }
                    return Index();
            }
        }
    }

    示例代码下载地址https://files.cnblogs.com/aehyok/MVCLinqWCF.rar






      

  • 相关阅读:
    【程序员面试宝典】第五章 程序设计基本概念
    win7打开或关闭windows功能 提示“出现错误,并非所有的功能被更改”,管理员权限惹的祸
    堆排序
    目态与管态的概念
    循环不变式的概念
    getchar()函数的返回值赋给char型,用if(ch=getchar() != EOF)测试,输入ctrl+z同样可以结束循环的分析
    java算法 -- 冒泡排序
    Java算法 -- 二分查找
    Sql知识点总结
    java实现 链表反转
  • 原文地址:https://www.cnblogs.com/aehyok/p/3039926.html
Copyright © 2020-2023  润新知