|
 |
栏目导栏 |
|
| |
|
|
|
|
 |
资料搜索 |
|
| |
|
|
|
|
 |
热门文章 |
|
| |
|
|
|
|
 |
最新文章 |
|
| |
|
|
|
| |
| |
|
|
|
| |
| Jimmy’s 使用Asp.Net Ajax 构建三层式Web 应用程序 |
|
我参阅、构建了不少Web 应用程序,一直想写一个系统的Tutorial出来,一方面是做个总结和归纳,一方面也是进行一下知识共享。OK,闲话不多说了,Let’s Go. q5vLinux联盟 q5vLinux联盟 q5vLinux联盟 q5vLinux联盟 本文是 “使用Asp.Net Ajax 构建三层式Web 应用程序” 系列文章的第一部分。在这一系列文章中,我将系统的讲述如何使用 Asp.Net Ajax 设计、构建、实现三层Web应用程序。本文的读者应该是有一定Asp.Net基础的开发者,同时要求对数据库、C#、Ajax、Web Service也有一定的了解,另外,这篇文章也适合那些准备使用ObjectDataSource 进行Web应用程序开发的程序员。这系列教程使用我目前正在使用的一个“个人理财程序”作为范例讲解,这个程序非常小,只有三个表,但麻雀虽小五脏俱全,我主要想利用它为大家阐明一些概念,可能功能并不完备,但对于教程所讨论的主题没有影响,感兴趣的话可以自行扩展它。 q5vLinux联盟 q5vLinux联盟 q5vLinux联盟 q5vLinux联盟 古人云:条条大道通罗马。所以,我这里讲述的,只是我个人的三层式Web应用程序实现,并不是说只有这一种实现方法,更不能说明这种实现方法是最好的。其实,现在我就可以明确地告诉大家,这个实现方法有一个缺陷,至于这个缺陷是什么,就让我卖个关子吧,等这系列教程写完后再告诉大家。 q5vLinux联盟 q5vLinux联盟 q5vLinux联盟 q5vLinux联盟 这系列教程计划分为五个部分(NOTE: 根据情况可能会有调整,如果一篇Part在Word里的页数超过15,我可能会考虑将它分成两个Part),其中每个部分的内容如下: q5vLinux联盟 q5vLinux联盟 q5vLinux联盟 q5vLinux联盟 l Part 1. 讲解三层式Web应用程序的概念,数据访问层的实现方式,“个人理财程序”的需求分析。 q5vLinux联盟 q5vLinux联盟 l Part 2. 讲解 系统的概要、详细设计,数据库的实现,业务对象类的实现步骤和方法。 q5vLinux联盟 q5vLinux联盟 l Part 3. 讲解 数据访问层 和 业务逻辑层 的代码实现。 q5vLinux联盟 q5vLinux联盟 l Part 4. 讲解 用户界面层 的实现,以及如何使用 ObjectDataSource 调用业务逻辑层中的对象和方法。 q5vLinux联盟 q5vLinux联盟 l Part 5. 讲解如何为 Part 4. 中实现的部分加上 Web Service 和 Asp.Net Ajax。 q5vLinux联盟 q5vLinux联盟 q5vLinux联盟 q5vLinux联盟 以下是几点说明: q5vLinux联盟 q5vLinux联盟 q5vLinux联盟 q5vLinux联盟 l 我会尽可能细致的讲解每一部分,而我工作又相当忙,所以花费的时间会比较长,我不能确切地告诉你,会在什么时候完全部成。 q5vLinux联盟 q5vLinux联盟 l 本文中,我有时候会说到“用户界面层”,有时候会说到“表现层”,这两个在本系列教程中是一回事。 q5vLinux联盟 q5vLinux联盟 l 阅读本文前强烈推荐阅读我的另一篇原创文章 “Jimmy’s 数据库对象命名探讨”。 q5vLinux联盟 q5vLinux联盟 l 你现在看到的并不是本系列教程的最终版本,我会根据大家的反馈对文章不断地进行改进。 q5vLinux联盟 q5vLinux联盟 l 本教程的 Source Code 和 T-SQL 将在教程全部结束后提供下载。 q5vLinux联盟 q5vLinux联盟 q5vLinux联盟 q5vLinux联盟 本系列教程使用的开发环境是 VS 2005 + SQL Server 2000,操作系统是 Windows Server 2003 Enterprise Edition。T-SQL 代码我只在 SQL Server 2000 下测试了,如果在 SQL Server 2005下不能通过,请反馈给我。(NOTE: 这里说一下我为什么不使用 SQL Server 2005,因为 SQL Server 2008 明年就发布了,微软更新换代的能力太强,如果每个新版本都要去掌握,会活得很辛苦,我打算把 SQL Server 2000用到SQL Server 2008 正式版发布的时候,然后直升2008。) q5vLinux联盟 q5vLinux联盟 q5vLinux联盟 q5vLinux联盟 q5vLinux联盟 q5vLinux联盟 三层式开发概述 q5vLinux联盟 q5vLinux联盟 分层式开发是一种开发模式,在这种模式中,用户界面层(用户所看到和与其交互的那部分)、业务逻辑层(业务规则(比如本例中每天的开销不能为负数)和业务对象)、以及数据访问层(对数据库进行查询和操作),从代码的角度来看,是分开的。 q5vLinux联盟 q5vLinux联盟 q5vLinux联盟 q5vLinux联盟 这种模式具有很多的优点: q5vLinux联盟 q5vLinux联盟 q5vLinux联盟 q5vLinux联盟 1. 你的代码非常的“干净”。可以试想一下,如果你把提交表单的ADO.NET数据库操作全都写到页面的 CodeBehind文件中,会是多么的凌乱?(NOTE:这差不多是每个Asp.Net入门者都干过的事情,其中包括我。) q5vLinux联盟 q5vLinux联盟 2. 更好的可维护性,程序员之间的分工明确,各层之间只需要知道调用接口就可以了,而不需要知道是如何实现的。 q5vLinux联盟 q5vLinux联盟 3. 更好的可移植性,可以联想一下 微软的数据访问技术 从 ODBC 到 OLEDB 到 ADO再到 ADO.Net 1.1 一直到如今的 ADO.NET 2.0,几乎每三年就会有一次变革,采用分层式开发,可以在系统升级的时候更少的受到影响。 q5vLinux联盟 q5vLinux联盟 4. 更好的对分布式应用程序的支持。(NOTE:提到分布式应用程序时常会遇到两个英文单词: Tier 和 Layer ,这两个单词的意思翻译过来都是 “层”,但是有什么区别呢?老外通常提到Tier 的时候,指的是物理上分层;提到 Layer 的时候,常指的是逻辑上分层。物理上分层说的简单点,就是用户界面层在一台服务器,业务逻辑层在一台服务器,数据访问层又在另一台服务器(也可以表现层和业务层在同一台服务器,数据访问层在一台服务器,总之三个层不在一台服务器)。而逻辑上分层我现在正在讲述,很容易就想得通:如果物理上分层了,逻辑上也一定分层了;但如果逻辑上分层了,物理上不一定是分层的,可以部署在同一台服务器上,比如我的这个“个人理财程序”。) q5vLinux联盟 q5vLinux联盟 q5vLinux联盟 q5vLinux联盟 q5vLinux联盟 q5vLinux联盟 为了给大家一个更生动的认识,我用PhotoShop画了个图给大家看看: q5vLinux联盟 q5vLinux联盟 q5vLinux联盟 这张图描述了这个应用程序中数据流动的大致方向。 q5vLinux联盟 q5vLinux联盟 q5vLinux联盟 q5vLinux联盟 请大家从用户和左边的箭头看起: q5vLinux联盟 q5vLinux联盟 q5vLinux联盟 q5vLinux联盟 1. 用户浏览网页时,首先面对的是用户界面层或者说表现层,如果用户进行一个对数据库查询的操作,请求首先会发送到业务逻辑层。 q5vLinux联盟 q5vLinux联盟 2. 业务逻辑层对用户提交的数据进行校验,如果有问题,将拒绝用户请求并给出错误提示;如果没有问题,业务逻辑层将用户请求递交给数据访问层。 q5vLinux联盟 q5vLinux联盟 3. 数据访问层充当业务逻辑层与数据库之间的一个桥梁,把请求递交给数据库,不应该在这一层再去做一些数据校验的工作,来自业务逻辑层的数据应该被认为是无误的,这层的代码相对于业务逻辑层来说是很清爽的。 q5vLinux联盟 q5vLinux联盟 4. 数据库进行查询后将结果集返回给数据访问层,接着再返回给业务逻辑层,最后呈现给用户。这是一个典型的冒泡过程。在这个过程中,任何没有Catch的异常都会抛出,冒泡到用户界面层,这也就是为什么你访问aspx的页面,看到的却是来自数据库的“Can’t connect to database”的原因。 q5vLinux联盟 q5vLinux联盟 q5vLinux联盟 q5vLinux联盟 q5vLinux联盟 q5vLinux联盟 个人理财Web程序介绍 q5vLinux联盟 q5vLinux联盟 q5vLinux联盟 q5vLinux联盟 我是一个不会理财的人,在过去两年零一个月的时间,一毛钱都没有攒下,一个人的时候,我时常思索为什么我的钱总是来也匆匆去也匆匆,在现在老婆房子女朋友都没有的三无情况下,这样继续下去将会给我的人生带来深远的影响。 q5vLinux联盟 q5vLinux联盟 q5vLinux联盟 q5vLinux联盟 沉默了许久之后,我终于觉悟了... ..我想做的第一件事,就是解决长期困扰我的头号问题 -– 我的钱都跑哪儿去了?于是,这个个人理财程序便应运而生了。 q5vLinux联盟 q5vLinux联盟 q5vLinux联盟 q5vLinux联盟 其实如果只是我一个人使用的话,只需要一个表,就足以构建这个应用程序了。我给这个表起名叫:DailyCost,用来记录每天的开销/收入项目,表的字段分别是: q5vLinux联盟 q5vLinux联盟 CostId:自动编号,主键。 q5vLinux联盟 q5vLinux联盟 Type:0,表示开销;1,表示收入 q5vLinux联盟 q5vLinux联盟 Purpost:开销用途/收入来源 q5vLinux联盟 q5vLinux联盟 Amount:数额 q5vLinux联盟 q5vLinux联盟 CostDate:开销日期 q5vLinux联盟 q5vLinux联盟 q5vLinux联盟 q5vLinux联盟 但是,建一个只有一个人使用的程序简直太浪费了,让我们来对它进行了一下扩展,让更多的人可以使用吧。这样,就很有必要再加一个 User 表,记录使用此系统的用户,这个表应该包含如下字段: q5vLinux联盟 q5vLinux联盟 UserId:自动编号,主键。 q5vLinux联盟 q5vLinux联盟 Name:用户的名字 q5vLinux联盟 q5vLinux联盟 BirthDay:生日 q5vLinux联盟 q5vLinux联盟 Phone:用户的电话 q5vLinux联盟 q5vLinux联盟 q5vLinux联盟 q5vLinux联盟 此时,应该修改DailyCost表,以实现参照完整性(NOTE:也叫外键约束)。给DailyCost表再加一个字段: q5vLinux联盟 q5vLinux联盟 FKUserId,此条消费记录是属于哪位用户的。 q5vLinux联盟 q5vLinux联盟 q5vLinux联盟 q5vLinux联盟 在现在这个苦力都拿手机的时代,人们的Phone是会有很多的,比如手机一个,办公室一个,家里一个。所以,我们应该把Phone字段抽象出来,形成与User表的一对多关系。 q5vLinux联盟 q5vLinux联盟 q5vLinux联盟 q5vLinux联盟 建立 Phone 表,字段如下: q5vLinux联盟 q5vLinux联盟 PhoneId:自动编号,主键。 q5vLinux联盟 q5vLinux联盟 Number:号码 q5vLinux联盟 q5vLinux联盟 Type:0,手机;1,家里;2,公司;3,其他 q5vLinux联盟 q5vLinux联盟 FKUserId:外键,此Phone是哪位用户的 q5vLinux联盟 q5vLinux联盟 q5vLinux联盟 q5vLinux联盟 OK,这部分就先介绍到这里,在后面的 概要/详细 设计中会再次讲解。(NOTE:概要设计和详细设计我合并了,因为这个应用程序比较小,合并到一起我想大家已经可以看明白,分开讲解可能会显得文章过于繁琐。) q5vLinux联盟 q5vLinux联盟 q5vLinux联盟 q5vLinux联盟 实现数据访问层的不同方式 q5vLinux联盟 与用户界面揉在一起的数据访问层 q5vLinux联盟 这就是上面提到过的“初学者访问层”,将ADO.NET 代码揉到CodeBehind的事件处理中去,这种方法几乎没有可维护性,对数据库的任何改动,比如增减一个字段,或者给某个存储过程重新命名,都要导致修改大量的相关文件。另外,这种方法还有一个致命的缺点:无法实现代码重用。其实这种方法不应该称作“层”,但是为了文章的完备性,我还是在这里把它提出来。 q5vLinux联盟 q5vLinux联盟 q5vLinux联盟 q5vLinux联盟 用这种方式写的代码通常都是这样的: q5vLinux联盟 q5vLinux联盟 q5vLinux联盟 q5vLinux联盟 protected void Page_Load(object sender, EventArgs e) q5vLinux联盟 q5vLinux联盟 { q5vLinux联盟 q5vLinux联盟 if (!Page.IsPostBack) q5vLinux联盟 q5vLinux联盟 { q5vLinux联盟 q5vLinux联盟 string sqlText = @"SELECT Purpose, Amount, q5vLinux联盟 q5vLinux联盟 Type FROM DailyCost WHERE CostId = 1"; q5vLinux联盟 q5vLinux联盟 q5vLinux联盟 q5vLinux联盟 using (SqlConnection conn = q5vLinux联盟 q5vLinux联盟 new SqlConnection(ConfigurationManager.ConnectionStrings["JimmyCost"] q5vLinux联盟 q5vLinux联盟 .ConnectionString)) q5vLinux联盟 q5vLinux联盟 { q5vLinux联盟 q5vLinux联盟 using (SqlCommand myCommand = new SqlCommand(sqlText, conn)) q5vLinux联盟 q5vLinux联盟 { q5vLinux联盟 q5vLinux联盟 conn.Open(); q5vLinux联盟 q5vLinux联盟 using (SqlDataReader myReader = myCommand.ExecuteReader()) q5vLinux联盟 q5vLinux联盟 { q5vLinux联盟 q5vLinux联盟 if (myReader.Read()) q5vLinux联盟 q5vLinux联盟 { q5vLinux联盟 q5vLinux联盟 txtPurpose.Text = myReader.GetString(0); q5vLinux联盟 q5vLinux联盟 txtAmount.Text = myReader.GetString(1); q5vLinux联盟 q5vLinux联盟 txtType.Text = myReader.GetString(2); q5vLinux联盟 q5vLinux联盟 } q5vLinux联盟 q5vLinux联盟 myReader.Close(); q5vLinux联盟 q5vLinux联盟 } q5vLinux联盟 q5vLinux联盟 conn.Close(); q5vLinux联盟 q5vLinux联盟 } q5vLinux联盟 q5vLinux联盟 } q5vLinux联盟 q5vLinux联盟 } q5vLinux联盟 q5vLinux联盟 } q5vLinux联盟 q5vLinux联盟 q5vLinux联盟 q5vLinux联盟 protected void btnSave_Click(object sender, EventArgs e) q5vLinux联盟 q5vLinux联盟 { q5vLinux联盟 q5vLinux联盟 string sqlText = @"UPDATE DailyCost SET Purpose='{0}', q5vLinux联盟 q5vLinux联盟 Amount='{1}', Type ='{2}' WHERE Id = 1"; q5vLinux联盟 q5vLinux联盟 using (SqlConnection conn = q5vLinux联盟 q5vLinux联盟 new SqlConnection(ConfigurationManager.ConnectionStrings["JimmyCost"] q5vLinux联盟 q5vLinux联盟 .ConnectionString)) q5vLinux联盟 q5vLinux联盟 { q5vLinux联盟 q5vLinux联盟 string sql = String.Format(sqlText, q5vLinux联盟 q5vLinux联盟 txtPurpose.Text, txtAmount.Text, txtType.Text); q5vLinux联盟 q5vLinux联盟 SqlCommand cmd = new SqlCommand(sql, conn); q5vLinux联盟 q5vLinux联盟 conn.Open(); q5vLinux联盟 q5vLinux联盟 cmd.ExecuteNonQuery(); q5vLinux联盟 q5vLinux联盟 conn.Close(); q5vLinux联盟 q5vLinux联盟 } q5vLinux联盟 q5vLinux联盟 } q5vLinux联盟 q5vLinux联盟 q5vLinux联盟 使用SqlDataSource 作为数据访问层 q5vLinux联盟 在这里我推荐给大家一本好书,由电子工业出版社出版的,奚江华写作的《圣殿祭祀的ASP.NET 2.0开发详解》。在这本书中,作者在第11章 — “新一代数据访问方式DataSource控件”中详细讨论了 SqlDataSource 的种种特性,其中,比较重要的就是使用代码后置的方法动态的创建和配置 SqlDataSource 控件,并提供对页面数据控件的绑定。这就提供了一种新的实现数据访问层的思路 – 使用SqlDataSource 作为数据访问层。 q5vLinux联盟 q5vLinux联盟 q5vLinux联盟 q5vLinux联盟 在这里不得不说明一点,ObjectDataSource 其实就是完全自定义的 SqlDataSource 控件,想想看你是如何使用 SqlDataSource 的?我想你一定在前端页面通过拖拽控件的方式使用过SqlDataSource ,也一定注意到 SqlDataSource 的几个重要属性,SelectCommand、UpdateCommand 等,在使用 SqlDataSource 时,向导自动为你生成 Sql 语句(也可以自己写),然后显示在.aspx文件中,如果你实现了 UpdateCommand、InsertCommand (SelectCommand是必须要实现的),SqlDataSource 也就具有了相应的功能。而 ObjectDataSource 是如何运作的呢?它要求你自己写全部的Code以实现 Command,区别就是,你可以把这些Command全部封装到类或者说业务逻辑层中去。 q5vLinux联盟 q5vLinux联盟 q5vLinux联盟 q5vLinux联盟 好了,说了这么多,让我们看看使用SqlDataSource作为数据访问层的典型页面吧。 q5vLinux联盟 q5vLinux联盟 q5vLinux联盟 q5vLinux联盟 <asp:SqlDataSource q5vLinux联盟 q5vLinux联盟 ID="SqlDataSource1" runat="server" q5vLinux联盟 q5vLinux联盟 ConnectionString="<%$ ConnectionStrings:JimmyConn %>" q5vLinux联盟 q5vLinux联盟 DeleteCommand="DELETE FROM [DailyCost] WHERE [CostId] = @original_Id" q5vLinux联盟 q5vLinux联盟 InsertCommand="INSERT INTO [DailyCost] ([Purpose], [Type], q5vLinux联盟 q5vLinux联盟 [Amount], [CostDate]) VALUES (@Purpose, q5vLinux联盟 q5vLinux联盟 @Type, @Amount, @CostDate)" q5vLinux联盟 q5vLinux联盟 SelectCommand="SELECT * FROM [DailyCost]" q5vLinux联盟 q5vLinux联盟 UpdateCommand="UPDATE [DailyCost] SET [Purpose] = @Purpose, q5vLinux联盟 q5vLinux联盟 [Type] = @Type, [Amount] = @Amount, q5vLinux联盟 q5vLinux联盟 [CostDate] = @CostDate WHERE [CostId] = @original_Id" OldValuesParameterFormatString="original_{0}" q5vLinux联盟 q5vLinux联盟 > q5vLinux联盟 q5vLinux联盟 <DeleteParameters> q5vLinux联盟 q5vLinux联盟 <asp:Parameter Name="original_Id" Type="Int32" /> q5vLinux联盟 q5vLinux联盟 </DeleteParameters> q5vLinux联盟 q5vLinux联盟 <UpdateParameters> q5vLinux联盟 q5vLinux联盟 <asp:Parameter Name="Purpose" Type="String" /> q5vLinux联盟 q5vLinux联盟 <asp:Parameter Name="Type" Type="Bool" /> q5vLinux联盟 q5vLinux联盟 <asp:Parameter Name="Amount" Type="Decimal" /> q5vLinux联盟 q5vLinux联盟 <asp:Parameter Name="CostDate" Type="DateTime" /> q5vLinux联盟 q5vLinux联盟 <asp:Parameter Name="original_Id" Type="Int32" /> q5vLinux联盟 q5vLinux联盟 </UpdateParameters> q5vLinux联盟 q5vLinux联盟 <InsertParameters> q5vLinux联盟 q5vLinux联盟 <asp:Parameter Name="Purpose" Type="String" /> q5vLinux联盟 q5vLinux联盟 <asp:Parameter Name="Type" Type=" Bool " /> q5vLinux联盟 q5vLinux联盟 <asp:Parameter Name="Amount" Type="Decimal" /> q5vLinux联盟 q5vLinux联盟 <asp:Parameter Name="CostDate" Type="DateTime" /> q5vLinux联盟 q5vLinux联盟 </InsertParameters></asp:SqlDataSource> q5vLinux联盟 q5vLinux联盟 q5vLinux联盟 q5vLinux联盟 很明显就可以看到,不仅关于数据访问的Sql 语句直接写到了 .aspx页面中,而且代码臃肿不堪。尽管你可以使用代码后置的方式去实现这些,但代价就是降低了开发效率,因为手写比你拖动控件、使用向导要慢得太多。 q5vLinux联盟 q5vLinux联盟 q5vLinux联盟 q5vLinux联盟 q5vLinux联盟 使用TableAdapter和 强类型的DataSet q5vLinux联盟 VS 2005 提供强类型的 DataSet ,可以通过 VS2005向导 来创建,熟练的话,是创建数据访问层最快的一种方式,微软官方站点 www.asp.net ,有一个关于数据访问的系列教程,目前出到快 70 章了(NOTE:我大概算了一下,可以出本900页的书了),仍在不断更新中,这个教程使用的就是这种模型。 q5vLinux联盟 q5vLinux联盟 q5vLinux联盟 q5vLinux联盟 这里我仅简要说明一下什么是强类型的DataSet,和普通的DataSet有什么区别,至于如何创建强类型的DataSet,需要一个独立的章节来介绍,我以后再发文章补上。 q5vLinux联盟 q5vLinux联盟 q5vLinux联盟 q5vLinux联盟 强类型DataSet(NOTE:英文叫Typed DataSet)并不是 .NET 框架直接提供的一系列类,而是从DataSet类继承而来的,下图先给大家演示了传统的DataSet和它包含的各个元素之间的关系。 q5vLinux联盟 q5vLinux联盟 q5vLinux联盟 这里黑色的菱形箭头表示的是合成的方向,下面这幅图中,空心的三角,表示的是泛化的方向。合成,说通俗一点,或者用数据库的术语来说(NOTE: 用在这里并不恰当,纯粹为了解说方便),就是多对一关系,拿这幅图来说,就是好多个 DataRow 合成了DataTable,同时DataTable 还有DataColumn,而DataColumn又可以有Constraint和DataRelation,最后,好多个DataTable和 DataRelation合成了DataSet。 q5vLinux联盟 q5vLinux联盟 q5vLinux联盟 q5vLinux联盟 相比之下,强类型DataSet是从这些类派生出来的。 q5vLinux联盟 q5vLinux联盟 q5vLinux联盟 这幅图该如何解读我就不详细解释了,留给大家一点思考的空间。 q5vLinux联盟 q5vLinux联盟 q5vLinux联盟 q5vLinux联盟 那又为什么称它们为“强类型”DataSet呢?因为在强类型DataSet中,是使用一种类型安全的方式来使用其中的每一个对象,光是说术语很难懂什么叫类型安全的方式,让我们看下面的代码范例吧。 q5vLinux联盟 q5vLinux联盟 q5vLinux联盟 q5vLinux联盟 我们先看一段使用传统DataSet的代码。 q5vLinux联盟 q5vLinux联盟 q5vLinux联盟 q5vLinux联盟 // 前面省略部分代码 q5vLinux联盟 q5vLinux联盟 SqlDataAdapter daDailyCost = new SqlDataAdapter(“Select * From DailyCost”, conn); q5vLinux联盟 q5vLinux联盟 q5vLinux联盟 q5vLinux联盟 DataSet dataSet = new dataSet; q5vLinux联盟 q5vLinux联盟 q5vLinux联盟 q5vLinux联盟 daDailyCost.Fill(dataSet, “ShowCost”); q5vLinux联盟 q5vLinux联盟 q5vLinux联盟 q5vLinux联盟 Console.WriteLine(dataSet.Tables[“ShowCost”].Rows[0][“CostId”].ToString()); q5vLinux联盟 q5vLinux联盟 q5vLinux联盟 q5vLinux联盟 可以发现,我们在获取一个字段的值时,需要使用DataSet的索引器,逐步获得DataSet层次结构的每一个层面,直到最后抵达行级,在这个过程中,任何的拼写错误都会导致错误。 q5vLinux联盟 q5vLinux联盟 q5vLinux联盟 q5vLinux联盟 现在再看看 强类型DataSet是如何运作的。 q5vLinux联盟 q5vLinux联盟 q5vLinux联盟 q5vLinux联盟 //前面省略部分代码 q5vLinux联盟 q5vLinux联盟 SqlDataAdapter daDailyCost = new SqlDataAdapter(“Select * From DailyCost”,conn); q5vLinux联盟 q5vLinux联盟 q5vLinux联盟 q5vLinux联盟 //DailyCostTD 是实现了的强类型dataSet,至于如何实现,我以后会另写文章 q5vLinux联盟 q5vLinux联盟 DailyCostTD dataSet = new DailyCostTD(); q5vLinux联盟 q5vLinux联盟 q5vLinux联盟 q5vLinux联盟 daDailyCost.Fill(dataSet,”ShowCost”); q5vLinux联盟 q5vLinux联盟 q5vLinux联盟 q5vLinux联盟 Console.WriteLine(dataSet.Customer[0].Purpose); q5vLinux联盟 q5vLinux联盟 q5vLinux联盟 q5vLinux联盟 在这里,大家似乎觉得这两个没太大区别,无非就是在 Console.WriteLine的时候少打几个字而已,其实不然,在你用强类型DataSet的时候,VS2005会提供智能提示(NOTE:就是打个i,int就显示出来了,你只要拍下空格就好了),这样,就大大降低了编写时发生手误的机会。 q5vLinux联盟 q5vLinux联盟 q5vLinux联盟 q5vLinux联盟 既然强类型DataSet这么好用,为什么不干脆使用它作为数据访问层呢?前面我也提到过,使用类型化DataSet是创建数据访问层最快的方式,你只需要建立一个.xsd数据集文件,然后拖拽控件,再使用向导设置一下基本就可以Run了。但是,代价就是几乎没有扩展性,因为代码都是自动生成的,你很难去修改它(NOTE:其实还是有办法可以改的,你可以通过写部分类的方式去扩展它),另外,重用性也比较差。 q5vLinux联盟 q5vLinux联盟 q5vLinux联盟 q5vLinux联盟 使用新一代的 LINQ q5vLinux联盟 还有一种方式就是使用LINQ,很多人可能还是第一次听说这个名词,那么我就稍微的介绍一下: q5vLinux联盟 q5vLinux联盟 q5vLinux联盟 q5vLinux联盟 简单来说,Linq 就是帮助编译器理解和实现内存中保存的对象集合的一组特性。这样说可能比较绕口,Linq中有一个组件,称做Linq for SQL,它提供了一个在运行时将关系数据库数据处理成对象的底层机制,并且还不丧失关系数据库的查询功能。它通过将面向语的查询翻译成数据库可执行的查询语句,再将语句提交给数据库,然后把数据库返回的结果集映射成开发者定义的对象来完成。 q5vLinux联盟 q5vLinux联盟 q5vLinux联盟 q5vLinux联盟 上面的说法如果没有实际动手体会一下,或者看一些范例,相信不是太好理解。我会再近期(NOTE:一周时间左右),陆续发布来自微软开发团队的ScottGu的“Linq 介绍”系列文章(NOTE:又是一个Part 1 到 Part 5)。 q5vLinux联盟 q5vLinux联盟 q5vLinux联盟 q5vLinux联盟 不使用Linq的主要原因是它现在还处于Beta版本,正式发布时可能还会有改进。另外,目前的主机大多都只支持到.Net Framework 2.0(NOTE:如果你拥有自己的服务器请保持沉默),所以使用LINQ尚为时过早。 q5vLinux联盟 q5vLinux联盟 q5vLinux联盟 q5vLinux联盟 使用自定义的业务逻辑层对象 q5vLinux联盟 终于,我们的主角登场了。很多情况下,业务对象只是一个由其他对象继承的简单的类,也可以实现一些接口让它变得更好用一些。在我们的这个系统中,Phone对象像下面这样: q5vLinux联盟 q5vLinux联盟 q5vLinux联盟 q5vLinux联盟 public class Phone q5vLinux联盟 q5vLinux联盟 { q5vLinux联盟 q5vLinux联盟 private int phoneid = -1; q5vLinux联盟 q5vLinux联盟 private string number; q5vLinux联盟 q5vLinux联盟 private PhoneType type; // PhoneType是一个枚举 q5vLinux联盟 q5vLinux联盟 q5vLinux联盟 q5vLinux联盟 public string Number{ q5vLinux联盟 q5vLinux联盟 get{return number;} q5vLinux联盟 q5vLinux联盟 set{number = value;} q5vLinux联盟 q5vLinux联盟 } q5vLinux联盟 q5vLinux联盟 //以下代码省略 q5vLinux联盟 q5vLinux联盟 } q5vLinux联盟 q5vLinux联盟 q5vLinux联盟 q5vLinux联盟 在实践中,通常业务对象只包含数据,而关于对象操作的方法则封装到业务逻辑中去。 q5vLinux联盟 q5vLinux联盟 q5vLinux联盟 q5vLinux联盟 好了,数据访问层的实现方法至此告一段落,下面让我们开始进行 需求分析吧。 q5vLinux联盟 q5vLinux联盟 q5vLinux联盟 q5vLinux联盟 q5vLinux联盟 需求分析 q5vLinux联盟 做任何开发之前,需求分析都是很重要的步骤,如果需求都没有搞好,就等于没有回答用户需要什么解决方案的问题,如果在需求分析不明确的情况下冒然进行开发,结果往往是苦战两个月,做出来的产品却不是用户想要的。另外,需求分析并不是一次成型的,在这个阶段,由于还没有深入到概要设计或者详细设计中去,对系统的理解可能并不完整,所以会时常回过头来修订需求分析。 q5vLinux联盟 q5vLinux联盟 q5vLinux联盟 q5vLinux联盟 由于这个“个人理财程序”的用户和开发人员都是我自己,所以需求分析可以认为只是打打字而已。 q5vLinux联盟 q5vLinux联盟 q5vLinux联盟 q5vLinux联盟 在这个Web应用程序中,我们要实现的功能主要有这些:(NOTE:我可能会根据情况进行添加或删减,这主要视文章的长度而定,我会在Word中尽量将教程控制在60页以下): q5vLinux联盟 q5vLinux联盟 q5vLinux联盟 q5vLinux联盟 1. 要求可以添加、编辑、删除用户 q5vLinux联盟 q5vLinux联盟 2. 要求可以添加、编辑、删除用户电话 q5vLinux联盟 q5vLinux联盟 3. 要求可以添加、编辑、删除每日的开销项目 q5vLinux联盟 q5vLinux联盟 4. 要求可以删除 某日、某月 的全部开销 q5vLinux联盟 q5vLinux联盟 5. 要求可以查看某天、某月、某年的花费报表 q5vLinux联盟 q5vLinux联盟 6. 要求可以统计每天、每月、每年各开销了多少钱 q5vLinux联盟 q5vLinux联盟 7. 要求可以统计历史花钱最高的日期和开销/收益的数额 q5vLinux联盟 q5vLinux联盟 8. 要求可以统计历史花钱最低的日期和开销/收益的数额 q5vLinux联盟 q5vLinux联盟 9. 要求可以统计自系统运行以来总共开销了多少钱 q5vLinux联盟 q5vLinux联盟 10. 要求可以统计自系统运行以来总共收益了多少钱 q5vLinux联盟 q5vLinux联盟 11. 要求可以查看某个用户所有的联系方式 q5vLinux联盟 q5vLinux联盟 q5vLinux联盟 q5vLinux联盟 总 结 q5vLinux联盟 本文是使用 Asp.Net Ajax 构建三层 Web应用程序的第一部分。 q5vLinux联盟 q5vLinux联盟 q5vLinux联盟 q5vLinux联盟 我们首先了解了什么是三层式开发模式,接着提出了一个很现实的需要解决的问题,并对这个问题做了一些简单的分析。 q5vLinux联盟 q5vLinux联盟 q5vLinux联盟 q5vLinux联盟 然后,我们花了很大的篇幅,讲解实现数据访问层的各种方式,并简要介绍了我们即将采用的方法。 q5vLinux联盟 q5vLinux联盟 q5vLinux联盟 q5vLinux联盟 最后,我们对这个“个人理财程序”做了一下简单需求分析。 q5vLinux联盟
Linux联盟收集整理 ,转贴请标明原始链接,如有任何疑问欢迎来本站Linux论坛讨论 |
|
|
|
|
|