ruciffa

  博客园 :: 首页 :: 联系 :: 订阅 订阅 :: 管理
  4 Posts :: 1 Stories :: 1 Comments :: 1 Trackbacks

2008年5月9日 #

     摘要: 引用原文地址:http://weblogs.asp.net/scottgu/archive/2007/11/13/asp-net-mvc-framework-part-1.aspx来自Scott Gu的blog中ASP.NET MVC系列,以下是译文ASP.NET MVC Framework (Part 1) 两周之前我写了一个ASP.NET MVC Framework Overview的blog... 阅读全文
posted @ 2008-05-09 00:40 Brandon 阅读(29) | 评论 (0)编辑

2008年5月6日 #

 

引用原文地址:http://weblogs.asp.net/scottgu/archive/2007/10/14/asp-net-mvc-framework.aspx

来自Scott GublogASP.NET MVC系列,以下是译文,如有不妥之处,请不吝指出。本文的立意是让人更容易理解,所以有些地方可能不会生硬的翻译原文,毕竟英语环境里面的某些话语直接用中文说反而会引起理解的障碍。

ASP.NET MVC Framework

这些年以来,很多人对ASP.NET改进要求之一就是让其能够在完全支持MVC(model-view-controller,模型-视图-控制器)架构下开发web应用程序。

上个周末我在AustinAlt.NET conference上,把我们team一直在开发的ASP.NET MVC framework做了第一次面向公众的演示说明。想要了解详细情况的话,你们可以看一下Scott Hanselmanblog here)上我的演示视频。

今年晚些时候,我们会发布一个ASP.NET MVC Framework的公开预览版本,大约明年中叶的时候我们就会把它作为一个完全支持的新特性正式集成到ASP.NET之内。

译者注:本文发布时间为October 14, 2007 10:41

什么是Model View Controller (MVC) Framework?

MVC是一个方法论层面上的framework,它的主要思想是把一个应用程序的实现划分为三个角色组件:models(模型), views(视图), controllers(控制器)

·          MVC模式的程序中,"Models" (模型)是负责维持状态的组件。一般来说,所谓的状态都保存在数据库当中.(比如: 我们在程序使用一个名为Product” 的类来接收来自SQL数据库当中一张名为Products”表的数据,我们在程序当中一般都是通过使用这个Product类来操作实际数据库中Products表里面的数据).

·          MVC模式的程序中,"Views" (视图)是负责显示面向用户界面(UI)的组件典型性的,UI都在模型数据的基础上被创建 (比如: 我们创造一个编辑Product 的视图,它上面的textboxdropdowncheckbox等控件都建立在Product 模型当前状态的基础之上).

·          MVC模式的程序中,"Controllers" (控制器)的工作是接收终端用户的需求操作,处理各种模型,最终选择一个视图,并把它作为UI显示给终端用户。要注意的是,在MVC模式的应用程序当中视图仅仅用来显示信息,而接收和应答用户的输入操作是控制器的工作。

使用MVC方法论的一个好处就是它可以帮助人们在一个应用程序内部更清晰地分离模型(Model),视图(View)和控制器(Controller)这三个模块。这样的话能够使程序的测试更加容易,因为这样就可以更清晰地定义不同程序组件之间的contract,并且只要根据它就能很容易地相互连接各个模块。

另外,MVC能够更好地支持测试驱动的开发模式( test driven development TDD) – 在你写实际的新代码之前,你就已经实现了自动的单元测试,并且使用它来定义和核实等待编写的代码的实际需求。

关于 ASP.NET MVC Framework的一些细节

一旦预览版提供下载后,几周之内我会发一些包含更深入的ASP.NET MVC framework学习材料的blog (在那之前,最好的学习方式是去看我的演示视频).

在此之前,先分享一些关于ASP.NET MVC framework 的细节。

·          它在默认设置下就实现了模块概念的清晰分离,应用程序的可测试性和测试驱动的开发模式.  MVC framework 内部的所有核心contract都是以接口为基础并且能够很容易地重写替换的 (包含了以接口为基础的内部IHttpRequest/IHttpResponse ). 在一个ASP.NET的进程当中,你可以在不运行控制器的情况下,对程序进行单体测试(这能使你的单元测试更加快速)  你也可以使用任何一个你所需要的单元测试框架在实现你的测试 (包括 NUnit, MBUnit, MS Test等等).

·          它是高度可扩展和易添加的.  MVC framework 中的每一个模块都被设计成容易替换和自定义的, (比如: 你可以有选择性的使用你自己的视图引擎,URL寻址策略,以及参数串行化等等). 它还支持使用既有的依赖注入以及控制反转容器模型(Windsor, Spring.Net, Nhibernate等等).

·          它包含了一个强大的URL映射组件,可以让你使用清晰的URL来建立你的应用程序.  URL不需要在内部扩展,而是被设计成更容易支持SEO REST-friendly的命名模式比如说, 在我上面说到的项目当中,我可以很容易地把/products/edit/4这个URL 映射为ProductsController类里面的名为"Edit"action方法, 或者把/Blogs/scottgu/10-10-2007/SomeTopic/这个URL 映射为一个BlogEngineController类中的名为"DisplayPost"action方法.

·          MVC framework 支持把既有的 ASP.NET .ASPX, .ASCX以及 .Master markup 文件当作视图模板使用 (这意味着你可以很容易地使用已有的诸如嵌套Master Page, <%= %> 内联代码片断, 声明好的服务器控件, 模板, 数据绑定, localization之类的ASP.NET 特性).  不过,使用它们的话,将会不再使用已有的ASP.NET post-back 到服务器的行为模式取而代之的是你把终端用户的操作需求发送到一个控制器类(Controller- 这样能够帮助你建立概念模块的清晰分离以及应用程序的可测试性 (这还意味着在MVC为基础的视图当中不会再有视图状态(viewstate以及页面生命周期这样的问题).

·          ASP.NET MVC framework 完全支持已有的ASP.NET 特性,比如forms/windows 身份验证, URL authorization, membership/roles, 输出数据的缓存(caching, session/profile状态管理, health monitoring, 配置系统以及provider架构等等.

Summary

如果你希望使用MVC的方法建立你的web应用程序,我想你会发现新的ASP.NET MVC Framework 的架构非常清晰而且容易使用它能够让你更容易的保持程序概念模块的相互分离,并能促进单元测试以及支持测试驱动的开发模式

在今后的几周内我会放出更多的学习资料,来揭示新的MVC特性是如何运作的,以及你应该如何去利用它们。

希望能够帮到你。

Scott

posted @ 2008-05-06 14:17 Brandon 阅读(22) | 评论 (0)编辑

2008年3月8日 #

相对而言,LINQ TO DataSetLINQ技术中最小的一块,虽然是DB中抽取出来的一个离线的操作模型,但毕竟对象也是个内存里面的object而已。所以和LINQ TO Object相比,大多数的操作都是一样的,不同只是要根据DataSetDataTable的结构标明字段而已。下面简单的列出LINQ TO DataSet相比LINQ TO Object一些要注意的特色。

 

Query UnTyped DataSet

 

和一般的LINQ相比,query对象是untyped DataSet的时候,使用Field<T>SetField<T>来读写不同的column字段,下面是一个简单的例子:

 

DataTable orders = ds.Tables["Orders"];

DataTable orderDetails = ds.Tables["OrderDetails"];

 

var query =

    from    o in orders.AsEnumerable()

    where   o.Field<DateTime>( "OrderDate" ).Year >= 1998

    orderby o.Field<DateTime>( "OrderDate" ) descending

    select  o;

 

在这里大致要注意三点

1.因为untyped DataSet没有实现IEnumerable<T> IQueryable<T>interface,所以如果想把它作为一个可以查询的对象的话,要先用AsEnumerable() 或者AsQueryable()转换一下,将它转换成IEnumerable<T>或者IQueryable<T>对象才能用LINQ去查询。如:from o in orders.AsEnumerable()

 

2.一般是使用使用Field<T>(“Column A”)SetField<T>(“Column A”)来读写不同的column字段对应的element,用它来访问相对于以前我们用ds.Tables["Orders"].Row[“RowA”][ “Column A”]的访问模式比起来,一个很大的好处就是可以避免null类型产生的exception。我们以前从DataSet里面取数据的时候,如果取的出来的是null,就会抛出exception,所以我们经常作类似if(ds.Tables["Orders"].Row[“RowA”][ “Column A”]!=null)的判断来包装我们进一步的逻辑处理,但是用Field<T>(“Column A”)就可以避免这种麻烦。因为Field<T>(“Column A”)nullable的。这个特性的由来是<T>这个泛型的使用,比如你取int类型数据的时候,如果你觉得它可能是null,那你就可以用Field<int?>(“Column A”)去取,这样就可以避免了exception的抛出。

 

3 .Field<T>SetField<T>是使用并不局限在LINQ query当中,在程序的其他地方也能使用,可以用它去替代以前的我们访问DataSet的方式,例如:

 

foreach( DataRow r in orderDetails.Rows ) {
    if (r.Field<decimal>( "UnitPrice" ) < 10 ){
        r.SetField<decimal>( "UnitPrice", 10 );
    }
}

 

 

Query Typed DataSet

 

这就更加简单了。对于定义了类型的DataSet,我们可以象查询内存中一般的object那样去查询它。例如:

 

var query =
    from    o in ds.Orders
    where   o.OrderDate.Year >= 1998
    orderby o.OrderDate descending
    select  new { o.OrderID, o.OrderDate,
                  Amount = o.GetOrder_DetailsRows().Sum(
                               od => od.UnitPrice * od.Quantity ) };

 

还有一个与untyped DataSet不同的地方是在查询它的时候不需要使用AsEnumerable() 或者AsQueryable()那样的转换方法了。因为所有定义好的DataSet都是继承了TypedTableBase<T>这个基类,而这个基类已经实现了IEnumerable<T>interface

 

 

Query DataSet中的relation

 

DataSet当中有时候也是有relation的,和DB一样,例如在下面的DataSet中加入relation

 

DataTable orders = ds.Tables["Orders"];
DataTable orderDetails = ds.Tables["OrderDetails"];
ds.Relations.Add( "OrderDetails",
                  orders.Columns["OrderID"],
                  orderDetails.Columns["OrderID"]);

 

如果我们想像在LINQ TO SQL里面一样通过relation来访问与其有相关关系的table,可以使用GetChildRows方法来取得与当前table相关联的那个table里面的DataRows,并将其返回为可以查询的IQueryable<T>对象。例如:

 

var query =
    from    o in orders.AsEnumerable()
    where   o.Field<DateTime>( "OrderDate" ).Year >= 1998
    orderby o.Field<DateTime>( "OrderDate" ) descending
    select  new { OrderID = o.Field<int>( "OrderID" ),
                  OrderDate = o.Field<DateTime>( "OrderDate" ),
                  Amount = o.GetChildRows( "OrderDetails" ).Sum(
                               od => od.Field<decimal>( "UnitPrice" )
                                     * od.Field<short>( "Quantity" ) ) };

 

这样我们就能通过relation来访问对象table了。

posted @ 2008-03-08 00:39 Brandon 阅读(387) | 评论 (0)编辑

2008年3月2日 #

背景简介

 

我想在很长一段时间内,MS的三个产品将是一个话题吧,也是一个未来方向上的热点。就是将在VS 2008 SP1当中发布的ADO.NET Entity Framework .NET 4.0中将要发布的ASP.NET MVC,以及刚刚推出了2.0版本,并且将一直进化的SilverLight. 前两者将弥补MS产品线上的空白,或者说以前MS产品当中存在着的一些缺陷,而第三个将使MS踏入新的RIA领域.

 

ADO.NET Entity Framework弥补的MS一直都没有介入的持久层技术市场。从背景上来说,持久层框架解决的是关系型数据库和程序模型之间的不匹配性。程序模型更加贴近我们的实际应用,我们需要很多模型来供我们来使用,从而模拟我们的业务逻辑。我们需要程序模型实体之间的封装,多态,组合,继承,多对多等关系。这样的面向对象的与我们日常生活和思考模式匹配的模型才能更好的实现我们的业务。但是我们的数据库却不是面向对象的,数据库是关系型的,它是无法实现面向对象模型当中一些诸如集成和组合的关系的。所以在数据库的发展迟迟没有突破性进展的情况下,我们的选择只能是使用持久层框架来做中间转换,消除数据库和我们程序模型的不匹配性。在java技术平台上,Hibernate作为最为我们常用的持久层框架已经发展了很长一段时间。但在MS技术平台上,除了NHibernate这个模仿品外,一直没有类似功能的框架产生,这对于追求任何技术都最好MADE IN MICROSOFTMS来说,无疑是相当不爽的事情。

 

ADO.NET Entity Framework就是这么一个背景下将要推出的框架。可以说从ADOADO.NET,再到ADOEF MS对于程序和数据库之间的中间层技术完成了从轻量级的工具到重量级的框架的转变,而MS特有的易用性依旧。

 

ADO.NET Entity Framework的组成

 

首先是建模的Schema,用于将程序模型和数据库实际模型通过映射关系连接起来

1. Conceptual SchemaCSDL:用于在程序层面上的建模,直接建立面向对象的各种模型

2. Storage SchemaSSDL:用来描述数据库里面的实际情况。

3. Mapping SchemaMSL:作为前面两个层次的中间层,来描述两者之间的映射关系。

 

然后是提供了对于建模后的数据的访问方式

1. Entity SQL: 改进后的T-SQL语句

2. Object Service:提供了类似于以前在ADO.NET当中使用connectioncommanddata adapterdataset来访问数据的方式,估计要照顾以前开发人员访问ADO.NET的习惯。

3. LINQ TO Entity

 

最后是提供了IDE工具,一个Entity Designer,来方便地创建模型。


LINQ Technology


很多人都认为.NET Framework 3.5其实只是个半成品,真正完成进化的将是4.0, 的确,从3.03.5唯一的加强就是LINQ技术的发布,远远不如当初从2.03.0的变化大,当初引入的让人眼前一亮的WCF, WPF, WWF, Cardspace, ASP.NET AJAX, C# 3.0等技术,相对于以前版本都是相当大的革新。ADO.NET Entity Framework要在SP里面发布,而SilverLight远远没有成熟,ASP.NET MVC还在beta版,可能这些东西完成版本才会在4.0里面集成,现在的.NET Framework 3.5只是一个过渡的产品。

 

谈到唯一的进化 LINQ技术的话,这方面的考虑可能MS是比JAVA领先一步的,以前从来把数据读写当作tool层面的小技术的MS已经开始把其当作VS当中专门的一个模块。现在的LINQLINQ TO Object(内存中数据的读写),LINQ TO XML(XML文件中数据的读写),以及LINQ TO ADO.NET(数据库层面上的读写). LINQ TO ADO.NET又包括了三个子模块,LINQ TO DataSetDataSet数据的读写),LINQ TO SQL(针对于SQL Server数据库的读写),以及LINQ TO Entity

 

LINQ TO Entity其实是直接读写程序模型,它要和ADO.NET Entity Framework配合使用,它读写的是ADO.NET Entity Framework建模出来的程序模型,LINQ TO Entity的本质是直接读写ADO.NET Entity Framework数据的一种访问方式。它忽略了数据库层面,直接访问了程序模型层面。

 

很多人都问过一些问题,比如为什么LINQ TO SQL无法实现继承,多表组合,多对多等关系啊,要怎么实现这些个复杂关系啊。其实从设计上而已,LINQ TO SQL就无法实现这些,真正能够实现这些关系的是ADO.NET Entity FrameworkLINQ to Entity

 

LINQ TO SQL不支持多表继承,包括一实体一具体表的继承体制和一实体一扩展表的继承体制。LINQ TO SQL只支持单表的继承,即用一张数据库表存储整个继承体系中所有实体的数据,简单来说就是按照同一个属性来生成不同的类的那种继承。LINQ TO SQL是一个tool层面上的技术,可以实现轻量级和快速的数据库访问开发。为数据库生成其对应的Entity Class。但是如果你想实现比更复杂的映射关系和继承关系,只能使用预定将要发布的ADO.NET Entity Framework以及LINQ TO Entities

 

ADO.NET Entity Framework并不包括在目前的VS 2008 RTM版本当中,可能会在2008年中作为VSService Pack发布,它是一个ORM层面上的框架,可以实现目前LINQ TO SQL无法实现的诸如Many-to-Many的关系映射,Entity InheritanceSingle Entity From Multiple Tables等更为复杂的关系。

 

两者的不同地方在于,你使用LINQ to SQL的时候,你的映射,产生的CLR/.NET类是和你的数据/数据库模型紧耦合或绑定的,如果你改变对象模型,那么你要直接修改这些类,同样如果数据模型改变,你要使用重新生成对象代码,而ADO.NET Entity Framework在数据/数据库模型上建立一个概念层/实体层,这使得你要先定义概念层/实体层,接着建立数据/数据库的脚本(描述),然后在一个影射层建立你的实体和数据之间的逻辑映射,这使得业务和数据源之间有了很好的藕合度和隔离。而LINQ to SQL无法达到这样的效果,所以LINQ to Entities和ADO EF的联合使用就能提供实体的继承,实体的组合等等

posted @ 2008-03-02 16:42 Brandon 阅读(123) | 评论 (1)编辑