ADO.NET Data Service是隨同Visual Studio 2008 SP1提供的用於構建在數據對象模型 (如EF-DEMX, LINQ-DBML) 之時來快速提供企業網內外的輕量級數據服務。ADO.NET Data Service Framework的目標是提供一個天生與web相結合的靈活的數據服務。它其中最醒目的特色就是經過URIs來指向以特定方式(JSON/ATOM)展示的數據(塊),並以REST方式來展示。所支持的URIs訪問方式經過對標準HTTP verbs如GET, POST, PUT和DELETE的支持來完成對數據的CRUD.web
本文會經過一個具體的例子來演示如何使用ADO.NET Data Service以及其部分特性。數據庫
ADO.NET Data Service是由兩部分組成的,一部分是其運行時,它提供了諸如Addressing(即URI Translation), Open Format for Data Representation(公開的數據表現形式-JSON/ATOM), 數據傳輸協議等。另外一部分就是數據訪問部分,這部分是能夠選擇的,LINQ或者Entity Framework都是能夠的,Data Service自己的功能就是將這些數據源暴露成一個面向web的數據服務。服務器
建立一個服務分爲兩步:架構
如何建立一個EDM咱們在這裏不想多講,下邊的圖和簡單步驟會告訴你如何來建立一個EDM。app
3.在Entity Data Model Wizard中設置ConnectionString.點擊下一步.ide
4.在接下來的選擇表、視圖的窗體中選擇你想要加入到EDM中的表。這裏咱們選擇Employees, Territories和EmployeesTerrories表,而後點Finish. 到此咱們的EDM已經完成了。接下來咱們要作的事在EDM的基礎上來構建Data Service.函數
5. 右鍵點擊項目並在彈出菜單中選擇添加新項目。在彈出的對話框中選擇 ADO.NET Data Service, 並將名稱改名爲NorthwindService.svc.經過這裏你會發現,其實ADO.NET Data Service本質上是一個WCF.this
6. Service自己已經創建,但如今尚未將數據暴露給客戶端,而且沒有相應的數據訪問控制。當點擊上一步中的Add按鈕後,系統會打開NorthwindService.svc.cs文件,在這裏咱們須要作以下更改來暴露數據。atom
要作到這兩點只須要更改一下所示的高兩部分便可。第一個高兩部分表示咱們將NorthwindEntities做爲咱們的數據源。NorthwindEntities是咱們剛纔建立的EDMX的類名,Employees等表都已經做爲其屬性被Mapping成對象。第二個高亮部分是控制EntitySet(其實就是對應的表一級)的訪問權限。例如你仍然能夠經過下邊的代碼僅僅暴露Employees對象的只讀權限:config.SetEntityAccessRule(「Employees」,EntitySetRights.AllRead.這樣,服務只會暴露Employees集合而且只接受讀取,而不能有更新操做。spa
public class NorthwindService : DataService<NorthwindEntities> { // This method is called only once to initialize service-wide policies. public static void InitializeService(IDataServiceConfiguration config) { // TODO: set rules to indicate which entity sets and service operations are visible, updatable, etc. // Examples: config.SetEntitySetAccessRule("*", EntitySetRights.All); // config.SetServiceOperationAccessRule("MyServiceOperation", ServiceOperationRights.All); } } |
大功告成,你能夠經過View In Browser來驗證你的工做是否正確。
在前邊提到過,Data Service經過URIs來指向a piece of data。也就是說咱們經過URL就能夠來作到訪問數據,而且具備必定的數據過濾功能。拋棄高級的查詢選項不說,基本的URL就能夠來訪問EntitySet和Entity,以致於某個字段,字段的值等等。經過瀏覽你的Northwind.svc,咱們能夠看到如下數:
這裏暴露了Employees和Territories兩個數據集,這和咱們以前設定的是相同的。經過如下的訪問列表,你能夠很容易的來在這個數據集合中導航,並獲取你想要的數據。
Resource |
URI |
Service |
http://localhost:4588/NorthwindService.svc/ |
Entity Set |
http://localhost:4588/NorthwindService.svc/Employees |
Entity |
http://localhost:4588/NorthwindService.svc/Employees(1) |
Relationship |
http://localhost:4588/NorthwindService.svc/Employees(1)/Address |
Property |
http://localhost:4588/NorthwindService.svc/Employees(1)/Address/City |
Property |
http://localhost:4588/NorthwindService.svc/Employees(1)/FirstName |
ADO.NET Data Service一樣提供瞭如下的查詢選項:
Option |
Description |
Example |
expand |
相似於LINQ中的LoadOptions,以此來指定加載此對象相關的經過expand指定的對象。若是須要加載多個對象,用逗號分隔。 |
http://localhost:4588/NorthwindService.svc/Employees(1)?$expand=Territories 同事加載當前employee對應的Territories. |
|
指定排序方式。語法爲:$orderby=Field [ASC|DESC], [Field[ASC|DESC]] |
http://localhost:4588/NorthwindService.svc/Employees?$orderby=FirstName |
Skip Top |
相似於LINQ中的Skip(PageSize * PageIndex).Take(PageSize)用來實現分頁。表示越過多少條記錄,取接下來開始的幾條記錄。也可分開始使用兩個選項。 |
http://localhost:4588/NorthwindService.svc/Employees?$orderby=FirstName&$skip=3&$top=3 http://localhost:4588/NorthwindService.svc/Employees? $skip=3 |
Filter |
經過filter這個參數能夠在URL裏傳遞過濾條件。 |
對於如上邊所示的查詢表達式,ADO.NET Data Service提供了一些函數和標記來幫助咱們組建適合的查詢表達式(Query Expression).下表總結了常見的組建Query Expression的標記、函數等,以供查詢和參閱。
Operator |
Description |
Operator |
Description |
eq |
Equal |
ne |
Not Equal |
gt |
Greater than |
ge |
Greater than or equal |
lt |
Less than |
le |
Less than or equal |
and |
Logical and |
|
Logical or |
not |
Logical negation |
() |
Precedence grouping |
Operator |
Description |
Example |
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 |
String Functions |
|||
bool substringof(string p0, string p1) |
bool endswith(string p0, string p1) |
||
bool startswith(string p0, string p1) |
int length(string p0) |
||
int indexof(string arg) |
string insert(string p0,int pos, string p1) |
||
string remove(string p0, int pos) |
string remove(string p0, int pos, int length) |
||
string remove(string p0, string find, string replace) |
string substring(string p0, int pos) |
||
string substring(string p0, int pos, int length) |
string tolower(string p0) |
||
string toupper(string p0) |
string trim(string p0) |
||
string concat(string p0, string p1) |
|
||
Date Functions |
|||
int day(DateTime) |
int hour(DateTime) |
int minute(DateTime) |
|
int month(DateTime) |
int second(DateTime) |
int year(DateTime) |
|
Math Functions |
|||
double round(double) |
decimal round(decimal) |
double floor(double) |
|
decimal floor(decimal) |
double ceiling(double) |
decimal ceiling(decimal) |
|
經過這些看似簡單的函數和邏輯/算數操做符,能夠在很大程度上經過URL來作一些簡單的查詢和過濾。經過分析查詢結果你會清楚的看到:
查詢攔截很是有用,它起個代理或者把關的做用。當你僅僅想把具備某種狀態或者特徵的數據返回給客戶端時,用攔截查詢就能夠實現。好比,數據庫中的Employee信息,對於已經離開公司的員工咱們會將其狀態設置爲Leave,而在咱們不打算將這些信息流露出去時,寫一個Query Interceptor僅僅返回狀態<>Leave的記錄,那麼全部客戶端請求與Employee有關的數據時將被強制只能獲得狀態不爲Leave的記錄。換句話說,Query Interceptor的代理函數返回的數據在表面上替換了Employees的記錄。
下邊的示例限定了客戶端僅能獲得國家是USA的Employees信息:
[QueryInterceptor("Employees")] public Expression<Func<Employees, bool>> ReturnUSAEmployees() { return e => e.Country == "USA"; } |
Query Interceptors是面向EntitySet(也就是Table)的,經過修改QueryInterceptorAttribute的參數,你能夠給任何一個EntitySet來建立一個查詢攔截器。看看咱們剛纔設置的查詢攔截器是否工做呢?
沒錯,僅僅返回了5條Country=USA的記錄。Nice!
看起來,Change Interceptors和Query Interceptors很類似,都是用來攔截客戶端操做的。不一樣的是,前一個word,一個是面向query的,一個是面向change的。顧名思義,Change Interceptors面向的就是提交到服務器的的數據更新操做:包括Add, Change 和Delete,分別對應在數據添加操做,數據更改操做和數據刪除操做—這些是由UpdateOperations參數來提供的。下邊的示例實現了在執行添加操做時,若是Employee實例的Country屬性爲空,則默認設置爲USA:
[ChangeInterceptor("Employees")] public void AssignDefaultCountry(Employees c, UpdateOperations operation) { if (operation == UpdateOperations.Add) { if (c.Country.Trim().Length == 0) { c.Country = "USA"; } } } |
不要忘記給這個方法加入ChangeInterceptor屬性。而對於所攔截的操做對象,一樣是經過更改ChangeInterceptorAttribute的參數來實現的。
ADO.NET Data Service 爲咱們提供了快速構建一個數據服務的平臺,但到目前爲止,除了數據庫中的對象(還不包括存儲過程),咱們仍然沒法加入本身的方法,這顯得好像很不靈活。固然,ADO.NET Data Service仍是爲咱們提供了這樣的一種方式來擴展已有的整套生成好的數據服務的。你能夠添加一些你本身的方法,例如操做存儲過程,本身的邏輯,返回特殊處理後的數據這樣的方法,而後經過添加WebGetAttribute來使其變成一個ServiceOperation來暴露給客戶。
[WebGet] public IQueryable<Employees> GetEmployeesByCountry(string country) { var employees = from c in this.CurrentDataSource.Employees where c.Country == country select c;
return employees; } |
同時還要設置這個方法的權限(InitializeService方法中):
config.SetServiceOperationAccessRule("GetEmployeesByCountry", ServiceOperationRights.All); |
如何去訪問這個方法呢?由於你沒法再meta中(實際上就是http://localhost:4588/NorthwindService.svc)找到對這個方法的描述。很簡單,直接試驗一下下邊的URL是否工做呢?
http://localhost:4588/NorthwindService.svc/GetEmployeesByCountry?Country='USA' |
服務端的設置好像該有的都有了哦?除了Data Service的表現方式:Atom仍是JSON,這個另行解決吧,起碼得有傳輸的數據包來展示。另外的有關客戶端消費的(服務端消費和客戶端AJAX消費)咱們在下一個話題中來介紹吧:)
點擊連接下載練習代碼: http://files.cnblogs.com/zlgcool/Allan.DataServiceDemo.rar