
Artikel ini menjelaskan cara menerjemahkan permintaan GraphQL ke OData dan menjalankannya dengan menulis
sedikit kode C #.
Bagaimana cara kerjanya
Gagasan utama dari proyek ini adalah terjemahan permintaan GraphQL ke OData, terjemahan pertanyaan OData ke pohon ekspresi, yang kemudian diterjemahkan ke dalam permintaan untuk ORM. Parsing permintaan GraphQL dan serialisasi hasilnya dilakukan menggunakan GraphQL untuk .NET . Penguraian kueri OData dilakukan menggunakan OData .NET Libraries . Penerjemahan kueri (GraphQL -> OData -> pohon ekspresi) dan pelaksanaannya dilakukan menggunakan OdataToEntity .
Akses langsung ke data dilakukan melalui ORM yang menjalankan pohon ekspresi yang dihasilkan. Pertanyaan pada berbagai ORM dijalankan melalui kelas abstrak OeDataAdapter dan implementasinya untuk:
- Kerangka Entitas OeEf6DataAdapter
- Entity Framework Core OeEfCoreDataAdapter
- Linq2Db OeLinq2DbDataAdapter
Pengguna hanya perlu memiliki konteks akses data (EF / EF Core - DbContext, Linq2Db - DataConnection).
Untuk informasi lebih lanjut tentang mengeksekusi query OData, lihat artikel saya sebelumnya, OdataToEntity, cara mudah untuk membuat layanan .Net Core OData .
Contoh penggunaan
Misalnya, kita akan menggunakan skema Star Wars , ORM EF Core, penyedia memori SQLite.
Pertama, Anda perlu membuat konteks akses data StarWarsContext . Kemudian, adaptor akses data StarWarsDataAdapter . Setelah Anda dapat mulai menjalankan permintaan:
String query = @" { human(id: ""1"") { name friends { name appearsIn { name } } } } ";
Permintaan GraphQL:
{ human(id: ""1"") { name friends { name appearsIn { name } } } }
Diterjemahkan ke OData:
Human?$filter=Id eq '1'&$select=Name&$expand=Friends($select=Name;$expand=AppearsIn($select=Name))
Diterjemahkan ke SQL:
SELECT "h"."Name" AS "Item1", "h"."Id" AS "Item2", CASE WHEN "t"."Id" IS NULL THEN CAST(1 AS BIT) ELSE CAST(0 AS BIT) END, "t"."Name" AS "Item10", "t"."Id" AS "Item20", CASE WHEN "EpisodeEnum"."Value" IS NULL THEN CAST(1 AS BIT) ELSE CAST(0 AS BIT) END, "EpisodeEnum"."Name" AS "Item11", "EpisodeEnum"."Value" AS "Item21" FROM "Hero" AS "h" LEFT JOIN "HeroToHero" AS "CharacterToCharacter" ON "h"."Id" = "CharacterToCharacter"."CharacterId" LEFT JOIN ( SELECT "Hero".* FROM "Hero" AS "Hero" WHERE "Hero"."CharacterType" IN (1, 2) ) AS "t" ON "CharacterToCharacter"."FriendId" = "t"."Id" LEFT JOIN "HeroToEpisode" AS "CharacterToEpisode" ON "t"."Id" = "CharacterToEpisode"."CharacterId" LEFT JOIN "Episodes" AS "EpisodeEnum" ON "CharacterToEpisode"."EpisodeId" = "EpisodeEnum"."Value" WHERE ("h"."CharacterType" = 1) AND ("h"."Id" = @__Item1_0)
Hasil JSON:
{ "data": { "human": [ { "name": "Luke", "friends": [ { "name": "R2-D2", "appearsIn": [ { "name": "NEWHOPE" }, { "name": "EMPIRE" }, { "name": "JEDI" } ] }, { "name": "C-3PO", "appearsIn": [ { "name": "NEWHOPE" }, { "name": "EMPIRE" }, { "name": "JEDI" } ] } ] } ] } }
SQL yang dihasilkan tidak memiliki masalah N + 1 kueri, semua data diperoleh dalam satu kueri.
Struktur Kode Sumber
Kode sumber dibagi menjadi dua bagian: di folder sumber - perpustakaan itu sendiri dan akses rakitan untuk berbagai sumber data, di folder tes - tes dan contoh kode.
Pustaka itu sendiri terletak di folder source / OdataEntity.GraphQL .
Tes tes / OdataToEntity.Test.GraphQL .
File solusinya sln / OdataToEntity.Test.GraphQL.sln .