Produkt ADO.NET Data Services, známý také pod kódovým jménem Astoria (pravděpodobně se název tak líbil, že pod ním i dnes můžete najít mnoho čerstvých článků), je sada nástrojů, které reflektují aktuální potřeby webových aplikací zažívající boom.
reklama
Produkt ADO.NET Data Services, známý také pod kódovým jménem Astoria (pravděpodobně se název tak líbil, že pod ním i dnes můžete najít mnoho čerstvých článků), je sada nástrojů, které reflektují aktuální potřeby webových aplikací zažívající boom.
Základem je služba dostupná přes standardní HTTP protokol. S daty pak můžete jednoduše provádět CRUD (Create, Read, Update, Delete) operace. Data Services „sedí“ nad Entity Frameworkem a využívají mapování, které nabízí. Pracujete tedy s konceptuálním modelem, nikoli přímo se strukturou úložiště. Data Services následně vrací data v podobě XML resp. Atom nebo JSON.
Abychom pochopili, jaké možnosti Data Services nabízí a jaké je chování, vytvoříme si pro potřeby článku aplikaci využívající jednoduchou databázi (skript naleznete na konci článku).
Nejprve si vytvoříme novou webovou aplikaci (Web Application). Přidáme položku „ADO.NET Data Service“. V projektu se nám nyní objevil soubor s příponou .svc. Následně přidejte standardně EF model a vyberte tabulky vytvořené v předchozím kroku. Výsledkem bude model jako na obrázku:

Model uložte a zavřete, více se jím nebudeme zabývat.
Vrátíme-li se k našemu souboru .svc, vidíme velké množství komentářů. Nejprve musíme do špičatých závorek přidat název třídy datového zdroje – např:
public class MyDataService : DataService<MyModel.MyEntities>
Protože standardně služba neposkytuje přístup k žádným datům, je třeba povolit přístup k vybraným množinám entit. Pro naši ukázku použijeme:
config.SetEntitySetAccessRule("*", EntitySetRights.All);
Čímž říkáme, že umožňujeme přístup bez omezení ke všem množinám entit v modelu. V závěru seriálu se podíváme na přesnější nastavení, včetně dalších možností.
Pokud nyní otevřete službu ve webovém prohlížeči, uvidíte seznam entit, které služba nabízí:
<?xml version="1.0" encoding="utf-8" standalone="yes" ?>
<service xml:base="http://localhost:2634/MyDataService.svc/" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:app="http://www.w3.org/2007/app" xmlns="http://www.w3.org/2007/app">
<workspace>
<atom:title>Default</atom:title>
<collection href="a">
<atom:title>a</atom:title>
</collection>
<collection href="b">
<atom:title>b</atom:title>
</collection>
<collection href="base">
<atom:title>base</atom:title>
</collection>
</workspace>
</service>
Pouhou navigací např. na http://localhost:2634/MyDataService.svc/base dostanete seznam všech řádků v tabulce „base“. Pokud chceme konkrétní záznam, stačí adresu pozměnit na např. http://localhost:2634/MyDataService.svc/base(2).
<?xml version="1.0" encoding="iso-8859-1" standalone="yes"?>
<entry xml:base="http://localhost:2634/MyDataService.svc/" xmlns:d="http://schemas.microsoft.com/ado/2007/08/dataservices" xmlns:m="http://schemas.microsoft.com/ado/2007/08/dataservices/metadata" m:type="MyModel.base" xmlns="http://www.w3.org/2005/Atom">
<id>http://localhost:2634/MyDataService.svc/base(2)</id>
<title type="text"></title>
<updated>2008-07-16T09:38:34Z</updated>
<author>
<name />
</author>
<link rel="edit" title="base" href="base(2)" />
<link rel="http://schemas.microsoft.com/ado/2007/08/dataservices/related/a" type="application/atom+xml;type=entry" title="a" href="base(2)/a" />
<link rel="http://schemas.microsoft.com/ado/2007/08/dataservices/related/b" type="application/atom+xml;type=entry" title="b" href="base(2)/b" />
<content type="application/xml">
<m:properties>
<d:id m:type="Edm.Int32">2</d:id>
<d:name>čokoláda</d:name>
<d:number m:type="Edm.Int32">6</d:number>
<d:some_datetime m:type="Edm.DateTime">2006-06-16T00:00:00</d:some_datetime>
</m:properties>
</content>
</entry>
Výsledek, který je nám vrácen je běžné XML (Atom) a je tedy jednoduché zpracovat jej v mnoha prostředích. Protože jsou velmi oblíbené AJAXové aplikace, je možné výsledek získat i v podobě JSON (JavaScript Object Notation).
V XML si všimněte, že obsahuje též odkazy na asociované entity – v mém případě „a“ a „b“. Stačí vzít element „base“ a přidat obsah atributu „href“ elementu „link“ a můžeme prohlížet entitu vztahující se k této. Např: http://localhost:2634/MyDataService.svc/base(2)/b. Navigovat je možné i přímo na jednotlivé vlastnosti entity. Např: http://localhost:2634/MyDataService.svc/base(2)/number.
Tyto jednoduché možnosti však nejsou vše co Data Services z dotazování nabízí. Vlastně, pokud by šlo jen o toto, dokážete si podobnou službu napsat během odpoledne. Kromě navigace na asociované entity a výběru podle primárního klíče, je možné využít bohatých možností pro „vyladění“ výsledku. Query string může obsahovat několik volitelných parametrů.
expand
Parametr expand umožňuje do výsledku automaticky „rozbalit“ i asociované entity a tím ušetřit nutnost dalších dotazů pro zjištění detailů. Vhodné pokud víte, že budete potřebovat další informace. Do parametru je možné zapsat více množin entit oddělených čárkou.
Příklad: http://localhost:2634/MyDataService.svc/base?$expand=b
value
Umožňuje vrátit přímo hodnotu vlastnosti jako plain-text (případně application/octet-stream), bez jakéhokoli obalování XML nebo JSON. Vrácena je pouze vlastní hodnota, žádné dodatečné informace (datový typ, …).
Příkad: http://localhost:2634/MyDataService.svc/base(1)/number/$value
top
Podobně jako přímo v SQL tento parametr zajistí vracení pouze x prvních výsledků.
Příklad: http://localhost:2634/MyDataService.svc/base?$top=2
skip
Parametr skip zajistí přeskočení prvních y výsledků. Používá se především v kombinaci s top pro stránkování.
Příklad: http://localhost:2634/MyDataService.svc/base?$skip=2
orderby
Předchozí dva parametry, mají význam zejména, pokud můžete výsledek různě seřadit. Parametr orderby dělá přesně toto. Řadit můžete podle více sloupců, samozřejmě sestupně i vzestupně (implicitní).
Příklad: http://localhost:2634/MyDataService.svc/base?$orderby=number asc,some_datetime desc
filter
Asi nejvýkonnějším parametrem je parametr „filter“, který poskytuje funkcionalitu podobnou „where“ podmínce v SQL. Použity jsou speciální operátory, aby se zamezilo problémům s rezervovanými znaky v URL:
| Logické operátory |
| eq |
Rovnost |
| ne |
Nerovnost |
| gt |
Větší než |
| ge |
Vetší než nebo rovno |
| lt |
Menší než |
| le |
Menší než nebo rovno |
| and |
Konjunkce |
| or |
Disjunkce |
| not |
Negace |
| Aritmetické operátory |
| add |
Sčítání |
| sub |
Odčítání |
| mul |
Násobení |
| div |
Celočíselné dělení |
| mod |
Zbytek po celočíselném dělení |
| Závorky |
| ( ) |
Závorky (priorita vyhodnocování) |
Textové řetězce jsou obaleny apostrofy. Dostupných je ještě několik speciálních funkcí, jejichž seznam naleznete na konci článku.
Příklad: http://localhost:2634/MyDataService.svc/base?$filter=number ge (4 mul 2) and number lt 100
create table base (id int identity primary key, id_a int, id_b int, name nvarchar(200), number int, some_datetime datetime);
create table a (id int identity primary key, x int);
alter table base add foreign key (id_a) references a(id);
create table b (id int identity primary key, y nvarchar(20));
alter table base add foreign key (id_b) references b(id);
| Funkce pro práci s řetězci |
| bool contains(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 replace(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) |
| Funkce pro práci s daty |
| int day(DateTime p0) |
| int hour(DateTime p0) |
| int minute(DateTime p0) |
| int month(DateTime p0) |
| int second(DateTime p0) |
| int year(DateTime p0) |
| Matematické funkce |
| double round(double p0) |
| decimal round(decimal p0) |
| double floor(double p0) |
| decimal floor(decimal p0) |
| double ceiling(double p0) |
| decimal ceiling(decimal p0) |
| Funkce pro práci s typy |
| bool IsOf(type p0) |
| bool IsOf(expression p0, type p1) |
| <p0> Cast(type p0) |
| <p1> Cast(expression p0, type p1) |