微軟3.5 SP1推出了新的數據訪問FrameWork,叫ADO.Net Data Services Framework
概念:
微软在 .NET 3.5 SP1 平台上,推了一组新的数据访问 Framework,叫做 ADO.NET Data Services。微软怕程序员太闲吗?为什么要创造 ADO.NET Data Services?Web Service 和 WCF 不就很好用了吗?本帖整理一些研讨会及网络上大内高手的观点,并提供一个可在 VS 2008 SP1 上执行的示例给大家下载参考;但本帖不提供 step by step 实作教学,因为网络上已经有一堆这种文章了 (参考本帖最下面的「参考文件」第 6、第 7 点的文章,照着用 VS 2008 + SP1 操作,即可达成本帖提供下载的示例)。
.NET 的 WCF 3.5,有一个很重要的新功能,是对 REST (Representational State Transfer) 的支持。听说一些知名大型网站,及 RoR 阵营,都开始逐渐抛弃 Web Service,改提供 REST 的服务。所以微软这边也不能闲着,也搞了一套 ADO.NET Data Services 来支持 REST 的概念。
1、所谓的 REST,如同字面上的意思,是要让开发人员和应用程序 (当然也包括异质平台的应用程序),能以简单到不能再简单的方式,去访问和撷取网络上的数据和资源。怎么个简单法?REST 用最单纯的 URL 网址,就让一般客户、应用程序能直接访问、写入远程主机上的数据库。此外,微软实作 REST 的 ADO.NET Data Services,亦有一套安全控管、存取权限控管的机制,不必担心安全性的问题。
相对于微软的 WCF Service 要做一些设定,以及过去大家常用的 Web Service,此二者和 REST、ADO.NET Data Services 比较起来,相对就显得较复杂、不够弹性,且 Web Service 还有最为人垢病的 performance 问题。
过去如果你是一间公司的 MIS,当 A 部门的员工需要某些数据,你可能会随手写一支 Web Service 开放这些数据给别人使用;过不久 B 部门的主管又需要别的数据,你可能就再写另一支 Web Service,开放另一台主机数据库中的数据给别人使用。日积月累下来,几十上百支的 Web Service 可能就难以维护和管理,如此做法就显得不够弹性。而且别人在呼叫这些 Web Service 时,必须先知道主机的位置、函数的名称及功能、传入的参数及类型,在引用上仍不够方便。
相对于微软的 WCF Service 要做一些设定,以及过去大家常用的 Web Service,此二者和 REST、ADO.NET Data Services 比较起来,相对就显得较复杂、不够弹性,且 Web Service 还有最为人垢病的 performance 问题。
过去如果你是一间公司的 MIS,当 A 部门的员工需要某些数据,你可能会随手写一支 Web Service 开放这些数据给别人使用;过不久 B 部门的主管又需要别的数据,你可能就再写另一支 Web Service,开放另一台主机数据库中的数据给别人使用。日积月累下来,几十上百支的 Web Service 可能就难以维护和管理,如此做法就显得不够弹性。而且别人在呼叫这些 Web Service 时,必须先知道主机的位置、函数的名称及功能、传入的参数及类型,在引用上仍不够方便。
2、但若透过 REST、ADO.NET Data Services,当你想公开某一台主机上的数据库 Northwind,给远程的一般 user、开发人员或应用程序访问 (包括 SELECT、INSERT、UPDATE、DELETE 等 CRUD 动作) 时,只要提供下列的 URL,搭配 HTTP Verbs (GET, POST, ...) 即可:
http://www.网站名称.com/Northwind
若要让他们能访问 Northwind 数据库中的 Products 表时,只要提供下列的 URL 即可:
http://www.网站名称.com/Northwind/Products
亦即 ADO.NET Data Services 是一个远程主机数据访问的「中介服务」,可由客户端、客户端应用程序,自行决定数据存取的内容和方式。
因此将来的 URL 指向的不再只是一个网址,而可能是某个数据库、数据来源、云端运算 [15,16,17];而且分布式环境中的 AJAX、WCF、Silverlight 等客户端应用程序,要使用这个 REST-based 服务也相当简单,尤其是 AJAX 不用再手工搞一堆 JavaScript;将来要在异质系统之间交换数据,将会有比 Web Service 更方便、更好用的选择,苦命的程序员将来或许真的能 REST 了 (虽然实际上只是梦想)。
在 .NET 平台方面,未来的 .NET Framework 4.0 及 Visual Studio 2010,仍有 ADO.NET Data Services Framework 2.0 的版本,也有新的 4.0 版的 System.Data.Services 函式库,因此预估 ADO.NET Data Services 将来应不至于被微软淘汰,程序员可放心学习。
-------------------------------------------------
本帖的示例代码下载点:
http://files.cnblogs.com/WizardWu/081214.zip
(执行本示例,需要 VS 2008 + SP1,以及 SQL Server 的 Northwind 数据库。若无法执行,请在本帖留言告知)
-------------------------------------------------
此一示例,是参考本帖最下方「参考文件」的第 6、第 7 这两篇文章的教学实作出来的,在此不再赘述过程。下载代码后,直接双击 testDS.sln,即会以 VS 2008 (SP1) 开启两个 project,如下图 1 所示。
图 1 鼠标指的 WebDataService.svc,即为开放在 URL 中给所有客户引用的 Data Services 服务
图 1 下方的 ds_server 项目,即为提供服务的 ADO.NET Data Services,透过一个 O/R Mapping 的 EDM 档案 [2],以和 ADO.NET Entity Framework 同样的做法,提供客户走访整个 SQL Server 2005 的 Northwind 数据库。
如同 WCF,在 ADO.NET Data Services 中也以 .svc 格式的档案提供网络上的服务。请您如上图 1,在 VS 2008 中,以鼠标右键,透过浏览器直接开启 WebDataService.svc 档案,此时您应该会看到如下图 2 的画面,亦即列出 Northwind 数据库中所有的表名称。
图 2 ADO.NET Data Services 默认会以 XML / Atom 格式回传所有的数据
假设您开启的网址如下:
http://localhost:埠号/ds_server/WebDataService.svc/
此时,只要在后面再加上表名称,即可 SELECT 出该表的所有内容。如下列语法,即为撷取出整个 Products 表的内容,并以 XML / Atom 格式回传:
http://localhost:埠号/ds_server/WebDataService.svc/Products
若您在 IE 中看不到上图 2 的内容,是因为以 Atom 格式回传,浏览器会自动进行格式化处理。请如下图 3 (以 IE 7.0 为例),关闭浏览器中的自动格式化动作,再按 F5 重新整理网页:
图 3 在 IE 7 中,取消勾选「启动摘要读取检视」
接下来您 (以及所有的客户端、客户端程序),即可直接透过此网址,去执行各种 ADO.NET Data Services 查询语法。例如下列语法,是要取出该表中的第一笔记录:
http://localhost:1056/ds_server/WebDataService.svc/Products(1)
下列语法,是只要取出该笔记录的 ProductName 字段存储值 (经版工测试,在 Firefox 3.x 上亦可执行):
http://localhost:1056/ds_server/WebDataService.svc/Products(1)/ProductName
下列语法,可查出 Orders 表中,CustomerID 为「ALFKI」的所有订单数据:
http://localhost:1056/ds_server/WebDataService.svc/Customers('ALFKI')/Orders
结果会查出六笔记录。其语法等同于:
SELECT * FROM Orders WHERE CustomerID='ALFKI'
当然您还可下各种参数,如:top、orderby、filter(大于、小于、等于、不等于)、skip、expand 等等。如下列语法,可取出该表中 top 20 笔的数据:
http://localhost:1056/ds_server/WebDataService.svc/Products?$top=20
当然您也可用一些逻辑算符、数学算符,以及 CURD 的操作,但目前不支持 sum、min、max、avg 函数,不支持 aggregate function 和 ISNULL、COALESCE 算符,但它自有一种 NULL 比对的语法,如下列语法,为取出 Products 表中,所有 UnitPrice 字段其内容不为 NULL 的记录:
http://localhost:1056/ds_server/WebDataService.svc/Products?$filter=UnitPrice ne null
有关其语法细节,有兴趣的网友们可参考本帖下方的参考文件 [11],以及网络上的文件。此外,ADO.NET Data Services 自有一套安全控管机制,例如只有某些账号能撷取某些表,某个群组的用户才有写入数据库的权限,程序员不必担心安全性的问题。
接下来要提到,若此 Data Services 要给客户端使用,您当然不可能丢一个 URL 叫他自己去下查询语法,因此各个程序员必须撰写客户端程序,去呼叫这个 Service。请您参考本帖先前的图 1,在 VS 2008 中,将上方的 ds_client 项目设定为「启始项目」;接着检视该项目中 Program.cs 其代码,如下图 4,将其中 localhost 后面的 port number,改成您先前用浏览器执行 WebDataService.svc 时,VS 2008 中虚拟 Web server 随机给的埠号;改完后存储,再按 F5 直接执行 ds_client 项目,即会看到图 4 右下方的 console mode 执行画面,会先引用 ds_server 项目中的 WebDataService.svc 服务,再用 C# 3.0 的 LINQ 去访问 Products 表,并列出其中两个字段的内容值。
图 4 透过 LINQ 及 EDM 做 O/R Mapping,客户端程序及程序员无须知道后端数据库位于何处,以及 SQL 语句该如何撰写
结论:
如同本帖的标题,为什么微软要创造 ADO.NET Data Services Framework?这门技术和 REST 的观念,是为了「简化」程序员的工作,在分布式环境或异质平台上做数据交换时,只要透过既有的 HTTP protocol 和 URIs 网址,就能提供比 Web Service 更简易的远程程序调用能力。且 ASP.NET AJAX 4.0、Silverlight 2.0、VS 2010 都已内建支持 ADO.NET Data Services,甚至微软将来的「云端服务 (Azure Service)」也支持该服务。或许未来微软要进一步拓展其野心,会叫各企业将其应用系统,都尽量由微软代管,经由云端服务 + Data Services 让企业用户觉得方便又省钱,也因此各大企业及 IT 从业人员,日后也更难脱离微软帝国的掌控。
------------------------------------------------------------
参考文件:
(1) ADO.NET 数据服务框架 (msdn)
http://msdn.microsoft.com/zh-cn/library/cc668792.aspx
(2) EDM 实体数据模型 (msdn)
http://msdn.microsoft.com/zh-cn/library/bb387122.aspx
(3) ADO.NET Data Services Framework 研讨会 (繁体中文)
http://blog.sina.com.tw/dotnet/article.php?pbgid=4907&entryid=580166
(4) REST 一下吧~ 从 Web Service 到 RESTful WCF 的心情 (繁体中文)
http://studyhost.blogspot.com/2008/11/rest.html
(5) 以 WCF 来开发 RESTful 风格的服务 (繁体中文)
http://studyhost.blogspot.com/2008/11/wcfrestful.html
(6) .Net Magazine 国际中文电子版, 2008 年 10 月号 (繁体中文)
http://www.netmag.com.tw/
(7) ADO.NET DATA Services 实验测试 (繁体中文)
http://blog.yam.com/kaizan/article/17120397
(8) Getting Started with ADO.NET Data Services (英文)
http://codebetter.com/blogs/david.hayden/archive/2008/01/08/getting-started-with-ado-net-data-services.aspx
(9) 一步一步学 Silverlight:数据与通信之 ADO.NET Data Services
http://kb.cnblogs.com/page/42890/
(10) 使用 ADO.NET Data Service (Astoria) 进行数据 CRUD 操作
http://www.cnblogs.com/lyj/archive/2008/04/11/1149136.html
------------------------------------------------------------
相关文件:
(11) 使用统一的 URI 对数据进行寻址的简单方案(ADO.NET 数据服务框架)
http://msdn.microsoft.com/zh-cn/library/cc668786.aspx
(12) System.Data.Services.Client 命名空间 (msdn)
http://msdn.microsoft.com/zh-cn/library/system.data.services.client.aspx
http://msdn.microsoft.com/zh-cn/library/system.data.services.aspx
(13) RESTful .NET
http://oreilly.com/catalog/9780596519209/
(14) Representational State Transfer (REST)
http://www.ics.uci.edu/~fielding/pubs/dissertation/rest_arch_style.htm
(15) 漫谈云端运算 (繁体中文)
http://jerrylovesrebol.blogspot.com/2008/12/blog-post_02.html
(16) 云端运算世代下的 Visual Studio 2010 与 .NET Framework 4.0 概观 (繁体中文)
http://blog.sina.com.tw/dotnet/article.php?pbgid=4907&entryid=580518
(17) 微软 Azure 云端服务平台 I - 检视 Azure 云端服务所带来的利益 (繁体中文)
http://blog.sina.com.tw/dotnet/article.php?pbgid=4907&entryid=580717
------------------------------------------------------------
Feedback
不错..
因果关系都讲清楚了..
不过感觉还是入门级的.呵呵
我有两个问题:
1,用这个模型,如果我想以Join几个table的结果来作为一个service我是不是要先创建对应的entity然后data service才能自动mapping这entity作为一个service ? 还是不用这么麻烦有什么简单的办法。
2, 另外如果我不想吧 的结果暴露在浏览器中安全方面应该怎么设置呢,可不可以设置access key?
说实在的比较讨厌ORM这个东东
整体来看,就是用效率换取“易用性”。
PS:能不能把图片存为PNG格式的,你图片软件的JPG算法实在是太差了。
ADO.NET Data Services Viewer Tool
I build this tool to help me build ADO.NET Data Services URL query.
Key Features:
1. URL IntelliSense
2. URL Tooltip
3. Data Grid View
4. XML Atom View
5. Data Service Metadata View
感谢各位前辈和大大热烈的回复。
小弟发此帖,是希望给网络上的朋友们,共同思考微软推出新技术的本质,以及微软想在未来玩什么花样;
并希望程序员不要落入,一直不断追逐新技术、怎么撰码、怎么实作的死胡同。
若要研究 Data Services 的更进阶实作,博客园及网络上,已经有其它更强的前辈发过相关的帖子了。
------------------------------------------
回应 2 楼的 Dnnmix 大大,
您第 2 点提到的,为 Data Services 的安全性,以及 authentication、authorization 的问题。
Data Services 自有一套控管机制,不过小弟我尚未玩得那么深入。
只知道在 Server-side 项目建立、加入一个 ADO.NET Data Service item 时,会同时产生
WebDataService.svc、WebDataService.cs
这两个档案,server-side 的程序员,就可在这个 WebDataService.cs 里做相关设定,如下 :
config.SetEntitySetAccessRule("*", EntitySetRights.All);
config.SetEntitySetAccessRule("*", EntitySetRights.AllRead);
config.SetEntitySetAccessRule("*", EntitySetRights.None);
config.SetEntitySetAccessRule("MyEntityset", EntitySetRights.WriteDelete);
您可参考以下的类库、API,以及 MSDN 和相关网络文件:
IDataServiceConfiguration..::.SetEntitySetAccessRule 方法 :
为指定实体集设置访问规则。
IDataServiceConfiguration..::.SetServiceOperationAccessRule 方法 :
为指定服务操作设置访问规则。
数据模型和数据服务实现(ADO.NET 数据服务/Silverlight):
(VS.95).aspx
ADO.NET Data Services in .NET 3.5 Service Pack 1 Beta1 with ASP.NET AJAX :
在 Visual Studio 中创建和访问 ADO.NET 数据服务 :
http://msdn.microsoft.com/zh-cn/library/cc668184.aspx
在 Web 服务领域公开和使用数据 (msdn magazine) :
http://msdn.microsoft.com/zh-cn/magazine/cc748663.aspx
Artech 前辈您说的是,
Data Services,确实在将来,是微软实现 Windows Azure、Azure Services 云端服务、云端托管企业系统和数据库,
等野望的最好数据存取、交换数据的利器,
至于一般企业的项目,是否适合导入 Data Services,则应由各企业行号的程序员、PM 和公司好高高层,
视成本、花费金钱、花费时间、机会成本,去自行判断。
因博客园好像有图片上载容量的限制,小弟我怕上载图片太多、档案太大,以后我这个账号,就没 quota 再上载图片了,
因此在用 HyperSnap 软件捉图时,才故意把 .jpg 图片分辨率存储得差一点,以节省博客园 hardware 的存储容量。
可拦截 Request / Response,插入自定义的 authentication 验证辑。其可在 .svc 里去定义。
// 自定义拦截器-查询
[QueryInterceptor("Employees")]
public Expression
{
return p=>p.Country=="China";
}
----------------------
QueryInterceptorAttribute 类 (msdn library)
方法上的 QueryInterceptorAttribute 将其批注为指定实体集上的查询拦截器。
命名空间: System.Data.Services
程序集: System.Data.Services(在 System.Data.Services.dll 中)
实体集级别授权和验证由使用 QueryInterceptorAttribute 批注的方法实现。ADO.NET 数据服务未实现安全策略,而是提供了必需的基础结构,以便服务开发人员编写自己的安全规则和业务验证。
----------------------
.NET Framework 3.5增强特性学习工具包已发布 :
你也可以使用服务拦截器增加加验证支持和自定义查询的服务操作。
* 可自定义 error handling、error message,替代默认值。
* 在 .svc 里去定义。
// 自定义 Data Services 错误处理
protected override void HandleException(HandleExceptionArgs args)
{
args.Exception = new DataServiceException(400, "这是自定义错误处理:" + args.ToString());
}
没必要故意转成简体嘛..简体文字搭配繁体图片和繁体名词..感觉怪怪的..呵呵
我随便一说 文章很不错