Menjalankan Permintaan GraphQL dengan OdataToEntity


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:


  1. Kerangka Entitas OeEf6DataAdapter
  2. Entity Framework Core OeEfCoreDataAdapter
  3. 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 } } } } "; //create data adapter var dataAdapter = new StarWars.StarWarsDataAdapter(false, "test"); //build odata model IEdmModel edmModel = dataAdapter.BuildEdmModelFromEfCoreModel(); //create graphql query parser var parser = new OeGraphqlParser(edmModel); //get graphql result ExecutionResult result = await parser.Execute(query); //serialize json String json = new DocumentWriter(true).Write(result); Console.WriteLine(json); 

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 .

Source: https://habr.com/ru/post/id429088/


All Articles