
рдЖрд▓реЗрдЦ рдореЗрдВ рд╡рд░реНрдгрд┐рдд рд╣реИ рдХрд┐ рдЧреНрд░рд╛рдлрд╝рдХреЙрд▓ рдкреНрд░рд╢реНрдиреЛрдВ рдХреЛ рдУрдбрдЯрд╛ рдореЗрдВ рдХреИрд╕реЗ рдЕрдиреБрд╡рд╛рдж рдХрд░реЗрдВ рдФрд░ рдЙрдиреНрд╣реЗрдВ рд▓рд┐рдЦрдХрд░ рдирд┐рд╖реНрдкрд╛рджрд┐рдд рдХрд░реЗрдВ
C # рдХреЛрдб рдХрд╛ рдереЛрдбрд╝рд╛ рд╕рд╛ред
рдпрд╣ рдХреИрд╕реЗ рдХрд╛рдо рдХрд░рддрд╛ рд╣реИ
рдкрд░рд┐рдпреЛрдЬрдирд╛ рдХрд╛ рдореБрдЦреНрдп рд╡рд┐рдЪрд╛рд░ рдУрдбрдЯрд╛ рдореЗрдВ рдЧреНрд░рд╛рдлрдХреНрдпреВрдПрд▓ рдкреНрд░рд╢реНрдиреЛрдВ рдХрд╛ рдЕрдиреБрд╡рд╛рдж рд╣реИ, рдУрдбрдЯрд╛ рдкреНрд░рд╢реНрдиреЛрдВ рдХрд╛ рдЕрдиреБрд╡рд╛рдж рдПрдХ рдЕрднрд┐рд╡реНрдпрдХреНрддрд┐ рдЯреНрд░реА рдореЗрдВ рдХрд┐рдпрд╛ рдЧрдпрд╛ рд╣реИ, рдЬрд┐рд╕реЗ рдмрд╛рдж рдореЗрдВ рдУрдЖрд░рдПрдо рдХреЗ рд▓рд┐рдП рдПрдХ рдХреНрд╡реЗрд░реА рдореЗрдВ рдЕрдиреБрд╡рд╛рджрд┐рдд рдХрд┐рдпрд╛ рдЧрдпрд╛ рд╣реИред рдПрдХ рдЧреНрд░рд╛рдлрдХреНрд▓рд╛рдЗрди рдХреНрд╡реЗрд░реА рдХреЛ рдкрд╛рд░реНрд╕ рдХрд░рдирд╛ рдФрд░ рдЙрд╕рдХреЗ рдкрд░рд┐рдгрд╛рдореЛрдВ рдХреЛ рдХреНрд░рдордмрджреНрдз рдХрд░рдирд╛ .NET рдХреЗ рд▓рд┐рдП рдЧреНрд░рд╛рдлрдХреЙрдЗрди рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░рдХреЗ рдХрд┐рдпрд╛ рдЬрд╛рддрд╛ рд╣реИред OData рдХреНрд╡реЗрд░реА рдХрд╛ рдЙрдкрдпреЛрдЧ OData .NET рд▓рд╛рдЗрдмреНрд░реЗрд░реАрдЬрд╝ рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░рдХреЗ рдХрд┐рдпрд╛ рдЬрд╛рддрд╛ рд╣реИред рдХреНрд╡реЗрд░реА рдЕрдиреБрд╡рд╛рдж (рдЧреНрд░рд╛рдлрдХреНрд▓рд╛рдЗрди -> рдУрдбрдЯрд╛ -> рдПрдХреНрд╕рдкреНрд░реЗрд╢рди рдЯреНрд░реА) рдФрд░ рдЙрдирдХреЗ рдирд┐рд╖реНрдкрд╛рджрди рдХреЛ рдУрдбреЗрдЯреЛрдЯреЗрдЗрдирд┐рдЯреА рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░рдХреЗ рдХрд┐рдпрд╛ рдЬрд╛рддрд╛ рд╣реИ ред
рдУрдЖрд░рдПрдо рдХреЗ рдорд╛рдзреНрдпрдо рд╕реЗ рдбреЗрдЯрд╛ рддрдХ рд╕реАрдзреА рдкрд╣реБрдВрдЪ рд╣реЛрддреА рд╣реИ, рдЬрд┐рд╕рдХреЗ рдкрд░рд┐рдгрд╛рдорд╕реНрд╡рд░реВрдк рдЕрднрд┐рд╡реНрдпрдХреНрддрд┐ рдХрд╛ рдкреЗрдбрд╝ рд╣реЛрддрд╛ рд╣реИред рд╡рд┐рднрд┐рдиреНрди рдУрдЖрд░рдПрдо рдкрд░ рдХреНрд╡реЗрд░реА рдЕрдореВрд░реНрдд рд╡рд░реНрдЧ OeDataAdapter рдФрд░ рдЗрд╕рдХреЗ рдХрд╛рд░реНрдпрд╛рдиреНрд╡рдпрди рдХреЗ рдорд╛рдзреНрдпрдо рд╕реЗ рдирд┐рд╖реНрдкрд╛рджрд┐рдд рдХреА рдЬрд╛рддреА рд╣реИрдВ:
- рдЗрдХрд╛рдИ рдврд╛рдВрдЪрд╛ OeEf6DataAdapter
- рдПрдВрдЯрд┐рдЯреА рдлреНрд░реЗрдорд╡рд░реНрдХ рдХреЛрд░ OeEfCoreDataAdapter
- Linq2Db OeLinq2DbDataAdapter
рдЙрдкрдпреЛрдЧрдХрд░реНрддрд╛ рдХреЛ рдХреЗрд╡рд▓ рдбреЗрдЯрд╛ рдПрдХреНрд╕реЗрд╕ рд╕рдВрджрд░реНрдн (EF / EF Core - DbContext, Linq2Db - DataConnection) рдХреА рдЖрд╡рд╢реНрдпрдХрддрд╛ рд╣реЛрддреА рд╣реИред
OData рдХреНрд╡реЗрд░реА рдХреЛ рдирд┐рд╖реНрдкрд╛рджрд┐рдд рдХрд░рдиреЗ рдХреЗ рдмрд╛рд░реЗ рдореЗрдВ рдЕрдзрд┐рдХ рдЬрд╛рдирдХрд╛рд░реА рдХреЗ рд▓рд┐рдП, рдореЗрд░рд╛ рдкрд┐рдЫрд▓рд╛ рд▓реЗрдЦ, OdataToEntity, .Net Core OData рд╕реЗрд╡рд╛рдПрдВ рдмрдирд╛рдиреЗ рдХрд╛ рдПрдХ рдЖрд╕рд╛рди рддрд░реАрдХрд╛ рджреЗрдЦреЗрдВ ред
рдЙрджрд╛рд╣рд░рдг рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░реЗрдВ
рдЙрджрд╛рд╣рд░рдг рдХреЗ рд▓рд┐рдП, рд╣рдо рд╕реНрдЯрд╛рд░ рд╡рд╛рд░реНрд╕ рд╕реНрдХреАрдорд╛, рдУрдЖрд░рдПрдо рдИрдПрдл рдХреЛрд░, рдореЗрдореЛрд░реА рдореЗрдВ SQLite рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░реЗрдВрдЧреЗред
рд╕рдмрд╕реЗ рдкрд╣рд▓реЗ рдЖрдкрдХреЛ StarWarsContext data access reference рдмрдирд╛рдирд╛ рд╣реЛрдЧрд╛ред рдЙрд╕рдХреЗ рдмрд╛рдж, StarWarsDataAdapter рдбреЗрдЯрд╛ рдПрдХреНрд╕реЗрд╕ рдПрдбрд╛рдкреНрдЯрд░ред рдЖрдк рдЕрдиреБрд░реЛрдз рдХреЛ рдирд┐рд╖реНрдкрд╛рджрд┐рдд рдХрд░рдирд╛ рд╢реБрд░реВ рдХрд░ рд╕рдХрддреЗ рд╣реИрдВ:
String query = @" { human(id: ""1"") { name friends { name appearsIn { name } } } } ";
рд░реЗрдЦрд╛рдВрдХрди рдХреНрд╡реЗрд░реА:
{ human(id: ""1"") { name friends { name appearsIn { name } } } }
OData рдореЗрдВ рдЕрдиреБрд╡рд╛рджрд┐рдд:
Human?$filter=Id eq '1'&$select=Name&$expand=Friends($select=Name;$expand=AppearsIn($select=Name))
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)
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 рдореЗрдВ N + 1 рдкреНрд░рд╢реНрдиреЛрдВ рдХреА рд╕рдорд╕реНрдпрд╛ рдирд╣реАрдВ рд╣реИ, рд╕рднреА рдбреЗрдЯрд╛ рдПрдХ рдХреНрд╡реЗрд░реА рдореЗрдВ рдкреНрд░рд╛рдкреНрдд рдХрд┐рдП рдЬрд╛рддреЗ рд╣реИрдВред
рд╕реНрд░реЛрдд рдХреЛрдб рд╕рдВрд░рдЪрдирд╛
рд╕реНрд░реЛрдд рдХреЛрдб рдХреЛ рджреЛ рднрд╛рдЧреЛрдВ рдореЗрдВ рд╡рд┐рднрд╛рдЬрд┐рдд рдХрд┐рдпрд╛ рдЧрдпрд╛ рд╣реИ: рд╕реНрд░реЛрдд рдлрд╝реЛрд▓реНрдбрд░ рдореЗрдВ - рд▓рд╛рдЗрдмреНрд░реЗрд░реА рдлрд╝реЛрд▓реНрдбрд░ рдФрд░ рд╡рд┐рднрд┐рдиреНрди рдбреЗрдЯрд╛ рд╕реНрд░реЛрддреЛрдВ рдХреЗ рд▓рд┐рдП рдЕрд╕реЗрдВрдмрд▓рд┐рдпреЛрдВ рдХрд╛ рдкрд░реАрдХреНрд╖рдг рдлрд╝реЛрд▓реНрдбрд░ рдореЗрдВ - рдкрд░реАрдХреНрд╖рдг рдФрд░ рдХреЛрдб рдЙрджрд╛рд╣рд░рдгред
рдкреБрд╕реНрддрдХрд╛рд▓рдп рд╕реНрд╡рдпрдВ рд╕реНрд░реЛрдд / OdataEntity.GraphQL рдлрд╝реЛрд▓реНрдбрд░ рдореЗрдВ рд╕реНрдерд┐рдд рд╣реИред
рдЯреЗрд╕реНрдЯ рдЯреЗрд╕реНрдЯ / OdataToEntity.Test.GraphQL ред
рд╕рдорд╛рдзрд╛рди рдлрд╝рд╛рдЗрд▓ sln / OdataToEntity.Test.GraphQL.sln ред