這篇是比較複雜的整合後產生的問題,關於ODtat和Web Api還有JayData的關係,近期會再有文章來補充。
最近花了一些時間查了這個問題,所以在這邊紀錄一下;這個問題主要是當我們使用EF進行多對多,或是1對多的時候產生的問題 ( 其實也不算是問題,主要還是因為Web API暫時不支援,但官方已經開始在撰寫了 );問題主要如下。
我們都知道,使用OData可以輕易的透過網址取得想要的資訊,例如取得Customer,但如果今天Customer和Order有關聯,而且一個Customer會有多個Order時 ( 也就是1對多關係 ),那OData還有一個$Expand的語法可以用 ( 題外話,多對多也適用… )。
而JayData官方的寫法如下,假設這個範例是DigitalArchives和SubCategory有關係,而且是多對多的關係,我們可以利用JayData來幫忙查詢。
$data.initService('/OData', function (dbFactory) { var mydatabase = dbFactory(); mydatabase.DigitalArchives.include("SubCategory") .filter("it.ID == 1") .forEach(function (c) { //do something }) });
而我們啟動瀏覽器,就可以看到,他會把上面的語法轉換成OData網址,並使用$Expand來includ相關聯的物件。
如果實際去看這個網址吐出來的東西,是找不到inclde的SubCategory屬性的。
會這樣的原因,是因為OData 3.0開始,為了讓OData傳輸的資料輕量,所以不會主動地把關聯的導覽屬性加進來,而要使用$Expand的方式,而目前Web Api還不支援$Expand( 官方已經在開始處理了 )。
而這邊也給大家看一下,如果是2.0版本,會出現怎樣的效果。如果想看舊版的,可以在輸入Content-Type: application/json;odata=verbose,呈現的效果如下。( 使用Fiddler2對http://localhost:2261/OData/DigitalArchives(1)偵錯。)
反正不管怎樣,就是因為Web API不支援…
所以該如何做呢??基本上,小弟目前只想到兩個方法,第一個是用OData Action,自己定義一個Action,但目前Action沒辦法傳回Collection,只能傳會Array…
第二個方法,就是使用如上圖的網址,但小弟目前也找不到JayData產生如上圖網址的方法,所以只能用Ajax去呼叫上面網址,取得JSON後再去處理。( Web Api 要另外撰寫方法。 )
總之,最後的結論,只能用第二種方式暫時的解,等Web Api更新。大體上是這樣了~
參考資料
- http://www.asp.net/web-api/overview/odata-support-in-aspnet-web-api/getting-started-with-odata-in-web-api/explore-the-odata-endpoint
- https://aspnetwebstack.codeplex.com/workitem/1074
- http://stackoverflow.com/questions/16455501/why-doesnt-my-odata-response-have-navigation-properties
- http://stackoverflow.com/questions/13998133/asp-net-webapi-odata-with-datajs-throws-an-error
- http://stackoverflow.com/questions/17154475/net-webapi-odata-actions-that-return-an-queryable
- http://stackoverflow.com/questions/16887105/webapi-odata-service-adding-foreignkey