项目介绍

这节将要把《一步一步学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到这里就结束了,看到这里应该已经算师父领进门了,后续的提高还要靠大家自己去琢磨。

TrackBack:http://www.cnblogs.com/lovecherry/archive/2007/09/02/878907.html

转载于:https://www.cnblogs.com/hdjjun/archive/2008/06/17/1223694.html

一步一步学Linq to sql(十):分层构架的例子相关推荐

  1. 一步一步学Linq to sql(一):预备知识

    从今天起将推出新手讲堂,首先从linq开始详细讲解.一步一步学Linq to sql(一):预备知识 什么是Linq to sql Linq to sql(或者叫DLINQ)是LINQ(.NET语言集 ...

  2. 【转】一步一步学Linq to sql(五):存储过程

    普通存储过程 首先在查询分析器运行下面的代码来创建一个存储过程: create proc sp_singleresultset as set nocount on select * from cust ...

  3. 一步一步学Linq to sql(七):并发与事务

      检测并发 首先使用下面的SQL语句查询数据库的产品表: select * from products where categoryid=1 查询结果如下图: 为了看起来清晰,我已经事先把所有分类为 ...

  4. 一步一步学Linq to sql(六):探究特性

      延迟执行 IQueryable query = from c in ctx.Customers select c; 这样的查询句法不会导致语句立即执行,它仅仅是一个描述,对应一个SQL.仅仅在需要 ...

  5. 一步一步学linq to sql(四)查询句法

    select 描述:查询顾客的公司名.地址信息 查询句法: var 构建匿名类型1 = from c in ctx.Customers select new { 公司名 = c.CompanyName ...

  6. 一步一步学linq to sql(二)

    DataContext与实体 DataContext类型(数据上下文)是System.Data.Linq命名空间下的重要类型,用于把查询句法翻译成SQL语句,以及把数据从数据库返回给调用方和把实体的修 ...

  7. 一步一步学Linq to sql(八):继承与关系

    论坛表结构 为了演示继承与关系,我们创建一个论坛数据库,在数据库中创建三个表: 1.  论坛版块分类表 dbo.Categories: 字段名 字段类型 可空 备注 CategoryID int no ...

  8. 一步一步学Linq to sql(三):增删改

    一.示例数据库 在数据库中创建一个名为GuestBook 的数据库, 在里面创建一个 tbGuestBook 的表,结构如下表. . 二.生产实体类 右键点击网站项目,选择添加新项,然后选择" ...

  9. 一步一步学Linq to sql:增删改

    示例数据库 字段名 字段类型 允许空 字段说明 ID uniqueidentifier 表主键字段 UserName varchar(50) 留言用户名 PostTime datetime 留言时间 ...

最新文章

  1. Swing如何正确的处理界面中的线程(EDT)
  2. React-Native 之 GD (一)目录结构与第三方框架使用与主题框架搭建
  3. Ubuntu Linux root password - default password
  4. C语言课设 成绩管理程序
  5. linux开机自动启动数据库,mysql随linux开机自动启动
  6. Linux中要重启apache服务与在windows是有很大的区别,下面我们来介绍一下
  7. 静态检查------SourceMonitor的学习和使用
  8. 新浪微博客户端(27)-格式化工具条显示数字
  9. plsql快捷执行方式_UG编程必备的快捷键,收藏转发!
  10. STL中常用容器的数据结构与底层实现
  11. eweishop 人人商城区别_微擎开发之人人商城添加第三方支付系列
  12. 红包大战复盘:谁赢得了这场春节游戏?
  13. 小米笔记本备份、SSD分区、U盘Ghost详解及对产品的建议
  14. n 个元素顺序入栈,则可能的出栈序列有多少种?转
  15. 2019年中总结之说走就走
  16. destoon php文件,destoon代码从头到尾捋一遍
  17. 【品牌DTC增长力】私域,你做的可能是“假的”
  18. UNCTF2020web方向部分题解
  19. window下Python查看已经启动的进程名称并关闭
  20. typhon字符串压缩

热门文章

  1. IBAction和IBOutlet
  2. 2016年程序员如何提高自己的方法有哪些?
  3. ios7学习之路六(隐藏状态栏 )
  4. 发布一个jquery插件--在Web下输入密码时提示大写锁定键(2012-05-03 10:20最后修改)...
  5. 简单的纯数字图像(如电话号码、数字验证码)识别
  6. 转:Mac文件权限操作详细记录
  7. noip模拟赛 入阵曲
  8. 三、常用行内元素与块元素
  9. android基本控件学习-----ProgressBar
  10. idea解决lombok注解失效问题