代码改变世界

ADO.NET Data Services Framework 基础概述

2010-03-07 21:59  闫妍  阅读(226)  评论(0编辑  收藏  举报

随着.NET Framework 4.0 及 Visual Studio 2010 的发布, ADO.NET Data Services Framework 2.0 的版本也将同时发布,新的.Net 4.0 也会支持 System.Data.Services 空间方法库,这说明ADODSF将会得到进一步的发展和壮大。

.NET 的 WCF 3.5,有一个很重要的新功能,是对 REST (Representational State Transfer) 的支持。

REST (Representational State Transfer) 用最单纯的 URL 网址,就让一般客户、应用程序能直接访问、写入远程主机上的数据库。此外,微软实现 REST 的 ADO.NET Data Services,亦有一套安全控管、存取权限控管的机制,不必担心安全性的问题。

相对于微软的 WCF Service 要做一些设定,以及过去大家常用的 Web Service,此二者和 REST、ADO.NET Data Services 比较起来,相对就显得较复杂、不够弹性和灵活。

以往我们对外提供数据访问会开发一个Web Service 或者WCF,当需求不断的扩大,Web 服务会变得越来越多,维护也会变得越来越难。

ADO.NET Data Services Framework 主要用途是可以很容易的将数据库服务公开在网络上,然后透过URL网址就可以对数据库进行CRUD的操作。ADO.NET Data Services能通过一个REST化的方式将数据以Web上的数据服务展示。使得应用可以以数据服务的方式展现数据,然后被应用在企业网络和互联网上的Web客户端中。

提示:在Visual Studio 2010 当中出现了一个框架 WCF RIA Services 使得使用和操作数据信息变的更加简单

ADO.NET Data Services Framework 的第一个实例程序

打开Visual Studio 2010 新建一个 Web 应用程序

image

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

新建项目 选择 WCF DataService

image

自动为项目添加引用

image

打开DataService文件,显示如下内容,注释部分提示我们,这个类文件还没有完成(代办事项 TODO),需要我们手动为他添加上所需要的特定配置

设置1:数据源类名称
设置2:设置实体集与服务,更新等操作
namespace DataService
{
    public class WcfDataService1 : DataService< /* TODO: put your data source class name here */ >
    {
        // This method is called only once to initialize service-wide policies.
        public static void InitializeService(DataServiceConfiguration config)
        {
            // TODO: set rules to indicate which entity sets and service operations are visible, updatable, etc.
            // Examples:
            // config.SetEntitySetAccessRule("MyEntityset", EntitySetRights.AllRead);
            // config.SetServiceOperationAccessRule("MyServiceOperation", ServiceOperationRights.All);
            config.DataServiceBehavior.MaxProtocolVersion = DataServiceProtocolVersion.V2;
        }
    }
}

 

添加项目Ado.Net Entity Data Model (ADO.Net Entity 已经无处不在了!),使用Northwind 数据库。

image

设置实体类

public class WcfDataService1 : DataService<NorthwindEntities> //添í加ó实μ体?集ˉ合?

 

设置Data Service 数据模型中表的访问控制

设置数据模型中表的访问控制。在DataServiceConfigration 中配置 EntitySetAccessRule,并传入给 InitializeService 方法。这是一个共享的方法,因此不管创建多少个DataService 文件类,该方法仅运行一次。在通过Visual Studio 调试时,如果你修改了该方法的代码,你需要记得强制重新编译。

public class WcfDataService1 : DataService<NorthwindEntities> //添í加ó实μ体?集ˉ合?
   {
       // This method is called only once to initialize service-wide policies.
       public static void InitializeService(DataServiceConfiguration config)
       {
           // TODO: set rules to indicate which entity sets and service operations are visible, updatable, etc.

           // 允ê许í读á取?所ù有D的?表í
           config.SetEntitySetAccessRule("*", EntitySetRights.AllRead);
           
           // 允ê许í操ù作÷所ù有D的?表í,?所ù有D权¨限T
           // config.SetEntitySetAccessRule("*", EntitySetRights.All);

           // 允ê许í服t务?方?法¨所ù有D权¨限T
           // config.SetServiceOperationAccessRule("MyServiceOperation", ServiceOperationRights.All);
           
           //配?置?协-议é版?本?,?为a2.0
           config.DataServiceBehavior.MaxProtocolVersion = DataServiceProtocolVersion.V2;
       }
   }

 

编译解决方案,运行DataService文件,你会得到如下结果

image

http://localhost:1342/WcfDataService1.svc/Orders

将返回Northwind数据库中所有Orders的数据种子(feed)。如果你使用 IE 或者Firefox浏览器,浏览器将自动对种子应用样式表CSS,

image

 

不过你可以右键点击,并查看源文件就可以看到实际返回的数据。

 

查询语句简单入门

以下语法源自网络:

接下来您 (以及所有的客户端、客户端程序),即可直接透过此网址,去执行各种 ADO.NET Data Services 查询语法。例如下列语法,是要取出该表中的第一笔记录:
http://localhost:1342/WebDataService.svc/Products(1)
下列语法,是只要取出该笔记录的 ProductName 字段存储值 (经版工测试,在 Firefox 3.x 上亦可执行):
http://localhost:1342/WebDataService.svc/Products(1)/ProductName
下列语法,可查出 Orders 表中,CustomerID 为「ALFKI」的所有订单数据:
http://localhost:1342/WebDataService.svc/Customers('ALFKI')/Orders
结果会查出六笔记录。其语法等同于:
SELECT * FROM Orders WHERE CustomerID='ALFKI'
当然您还可下各种参数,如:top、orderby、filter(大于、小于、等于、不等于)、skip、expand 等等。如下列语法,可取出该表中 top 20 笔的数据:
http://localhost:1342/WebDataService.svc/Products?$top=20
当然您也可用一些逻辑算符、数学算符,以及 CURD 的操作,但目前不支持 sum、min、max、avg 函数,不支持 aggregate function 和 ISNULL、COALESCE 算符,但它自有一种 NULL 比对的语法,如下列语法,为取出 Products 表中,所有 UnitPrice 字段其内容不为 NULL 的记录:
http://localhost:1342/WebDataService.svc/Products?$filter=UnitPrice ne null
此外,ADO.NET Data Services 自有一套安全控管机制,例如只有某些账号能撷取某些表,某个群组的

 

Ado.net数据服务url格式

 

  1. The data service URI.URI<service>对应发布的数据服务文件NorthwindDataService.svc. 比如:http://localhost:27383/SimpleDataService/NorthwindDataService.svc/.
  2. The entity-set name (optional).查看数据服务下面的实体名称,比如 /Orders 返回所有Orders表中记录,如果该实体包含关键字,要通过关键字查询 '10248, 则URI可以表示为/Orders(10248).还可以通过扩张的筛选表达式实现更复杂的查询
  3. A navigation property (optional).导航属性可以通过URI实现将有关联关系的实体查询出来比如Orders下面的子表Order_details.查询orders关键字(10248)下面明细记录 /Orders(10248)/Order_Details

查询字符串选项

Option

Description

Example

expand

The 'expand' option allows you to embed one or more sets of related entities in the results. For example, if you want to display a customer and its sales orders, you could execute two requests, one for /Customers('ALFKI') and one for /Customers('ALFKI')/Orders. The 'expand' option on the other hand allows you to return the related entities in-line with the response of the parent in a single HTTP request.

You may specify multiple navigation properties to expand by separating them with commas, and you may traverse more than one relationship by using a dot to jump to the next navigation property.

--a customer with related sales orders
/Customers('ALFKI')?$expand=Orders

--a customer with related sales orders and employee information related to those orders
/Customers('ALFKI')?$expand=Orders/Employees

--Orders with related employees information and related shipper information
/Orders(10248)?$expand=Employees,Shippers

orderby

Sort the results by the criteria given in this value. Multiple properties can be indicated by separating them with a comma. The sort order can be controlled by using the "asc" (default) and "desc" modifiers.

/Customers?$orderby=City

/Customers?$orderby=City desc

/Customers?$orderby=City desc,CompanyName asc

skip

Skip the number of rows given in this parameter when returning results. This is useful in combination with "top" to implement paging (e.g. if using 10-entity pages, saying $skip=30&top=$10 would return the fourth page). NOTE: Skip only makes sense on sorted sets; if an orderby option is included, 'skip' will skip entities in the order given by that option. If no orderby option is given, 'skip' will sort the entities by primary key and then perform the skip operation.

--return all customers except the first 10

/Customers?$skip=10

--return the 4th page, in 10-row pages

/Customers?$skip=30&$top=10

top

Restrict the maximum number of entities to be returned. This option is useful both by itself and in combination with skip, where it can be used to implement paging as discussed in the description of 'skip'.

--top 5 sales orders

/Customers?$top=5

--top 5 sales orders with the highest TotalDue

/Orders?$orderby=TotalDue&$top=5

filter

Restrict the entities returned from a query by applying the expression specified in this operator to the entity set identified by the last segment of the URI path.

-- all customers in London

/Customers?$filter=City eq 'London'

-- Match all Customers with the value of the property 'fullname' equal to 'Wayne, John' /Customers?$filter='Wayne, John' eq insert(ContactName, length(lastname), ',')

 

查询表达式

Operator

Description

Example

Logical Operators

   

eq

Equal

/Customers?filter=City eq 'London'

ne

Not equal

/Customers?filter=City ne 'London'

gt

Greater than

/Product?$filter=UnitPrice gt 20

ge

Greater than or equal

/Orders?$filter=Freight ge 800

lt

Less than

/Orders?$filter=Freight lt 1

le

Less than or equal

/Product?$filter=UnitPrice le 20

and

Logical and

/Product?filter=UnitPrice lteq 20 and UnitPrice gt 10

or

Logical or

/Product?filter=UnitPrice lteq 20 or UnitPrice gt 10

not

Logical negation

/Orders?$ ?$filter=not endswith(ShipPostalCode,'100')

Arithmetic Operators

   

add

Addition

/Product?filter=UnitPrice add 5 gt 10

sub

Subtraction

/Product?filter=UnitPrice sub 5 gt 10

mul

Multiplication

/Orders?$filter=Freight mul 800 gt 2000

div

Division

/Orders?$filter=Freight div 10 eq 4

mod

Modulo

/Orders?$filter=Freight mod 10 eq 0

Grouping Operators

   

( )

Precedence grouping

/Product?filter=(UnitPrice sub 5) gt 10

更多详细的说明请查看(http://msdn.microsoft.com/en-us/library/cc907912.aspx)

客户端如何去使用Data Service

第一种 : .Net Client 类库方式

using System.Data.Services.Client;

namespace DataService
{
    public partial class _Default : System.Web.UI.Page
    {
        protected void Page_Load(object sender, EventArgs e)
        {
            DataServiceContext dsc = new DataServiceContext(new Uri("http://localhost:1342/WcfDataService1.svc/Orders"));
            
            //查é询ˉ字?符?串?
            var query = dsc.Execute<Orders>(new Uri("http://localhost:1342/WcfDataService1.svc/Orders"));
            
            GridView1.DataSource = query;
            GridView1.DataBind();
        }
    }
}

 

第二种:  通过Service Reference创建客户端应用

 

image

 

 

using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.UI;
using System.Web.UI.WebControls;

namespace DataService
{
    public partial class WebForm1 : System.Web.UI.Page
    {
        protected void Page_Load(object sender, EventArgs e)
        {
            ServiceReference1.NorthwindEntities ne = new ServiceReference1.NorthwindEntities(new Uri("http://localhost:1342/WcfDataService1.svc"));

            //查é询ˉ字?符?串?
            //与?前°面?使1用?Client 引y用?一?样ù,?实μ际ê上?也2是?使1用?了?Data Service 的?查é询ˉ方?式?和í接ó口ú,?只?是?通¨过y代ú理í来′访?问ê了?
            var query = ne.Execute<ServiceReference1.Orders>(new Uri("http://localhost:1342/WcfDataService1.svc/Orders"));
            
            GridView1.DataSource = query;
            GridView1.DataBind();
        }
    }
}

 

源代码下载:

DataService.rar

 

 

fiddler 工具

介绍:

http://www.infoq.com/cn/news/2009/03/fiddler

代理:

http://www.fiddler2.com/fiddler2/version.asp