Սերվերային և ինտերֆեյսային պրոյեկտների հիմնական կմախքը

Vachagan Mirzoian
5 min readDec 31, 2021

Ժամանակակից ծրագրային ապահովման ամենակիրառվող ճարտարապետությունը Client–Server մառուցվածքն է։ Սերվերն իր հեթին պատասխանատու է տվյալներ բազաների համար։ Թեև ծրագրավորողը կարող է բավարարվել տեքստային հարցումներով, վերջնական օգտատերերի համար պետք է ստեղծվի հարմար ինտերֆեյս։ Արդյունքում ունենում են սկզբունքորեն իրարից տարբերվող 2 կտոր։ Կախված ծրագրի լրջությունից, կարող են լինել բազում շերտեր՝ բազայի տվյալների պահման, տվյալների ստացման մեխանիզմների, տվյալների վերջնական ներկայանցման և այլնի համար։ Մենք կունենանք 2 պրոյեկտ՝ բազայի և ներկայացման համար։

Ներկայացման համար պետք է ստեղծել Mode-View-Controller պրոյեկտ։

Անուն տալ այսպես՝

Ցանկալի է ոչինչ չփոխել։

Բազայի հետ աշխատելու համար պետք է ավելացնել «Domain» անունով Class Library, որը պատասխանատու է լինելու մոդելների համար։

Հաջորդ քայլով պետք է ավելացնել հղումներ։ «MVCPresentation»–ը կախված է լինելու «Domain»–ից։ Ավելի մեծաքանակ պրոյեկտներ ունենալու դեպքում պետք է լինի մի «assembly», որը ոչ մի ուրիշ պրոյեկտից կախված չէ, հակառակ դեպքում կունենանք փակ շղթա։ Կարելի է նաև MVCPresentation.csproj ֆայլում ավելացնել կոդ։

Ծրագիրն առաջին անգամ աշխատեցնելու դեպքում կտեսնենք նման հարցումներ։

DbDomain պրոյեկտը պատասխանատու է տվյալների բազայի համար։ Դրա մեջ պետք է մոդելներ ավելացնել, որոնց հիման վրա բազայում գեներացվելու են աղյուսակները։ Ստեղծենք Human և Car անունով կլասներ, որոնք իրենց մեջ պարունակելու են property–ներ։ Car կլասի «public virtual ICollection<Human>? Humans { get; set; }» տողով Human աղյուսակում ստեղծվելու է Car–ի վրա հղվող foreign key։ Հետո ավելացնենք DataContext անունով կլաս, որն իր էությամբ համընկնում է հենց բազայի հետ և որպես property պարունակում DbSet<T> տիպի մոդել–կլասները։ Այն ժառանգվում է DbContext հիմնային կլասից։ Տվյալների բազայի հետ աշխատելու համար օգտագործելու ենք Entity Framework, որը ծրագրավորման լեզվով գրված կոդի և բազաների միջև կապ ապահովող ինտերֆեյս է, այլ կերպ՝ object–relational mapper։ DbDomain — ին պետք է nuget package–ներից ավելացնել Microsoft.EntityFrameworkCore.UseSqlServer և Microsoft.EntityFrameworkCore փաթեթները։

DataContext–ն ունենում է հետևյալ տեսքը՝

MVCPresentation–ի Programm կլասի Top–level statement–ներում DataContext–ը հետևյալ կոդով պիտի ավելացնենք սերվիսներին։

UseSqlServer–ը մեր կողմից օգտագործվող տվյալների բազայի պրովայդերն է: DefaultConnection–ը Connection String–ն է, որը սահմանվում է appsettings.json–ում։ Սերվերի Properties հատվածում, նրա հետ ֆիզիկական կապ հաստատելուց հետո, կարելի պատճենել այն։ Connection String–ն ունի հետևյալ տեսքը՝

«Data Source»–ը սերվերի անվանումն է, «Initial Catalog»–ը՝ բազայի։ Պարզության համար կարելի է բաց թողնել մնաացած պարամետրերը։

Միգրացիաների համար MVCPresentation պրոյեկտում պիտի ավելացվի Microsoft.EntityFrameworkCore.Design փաթեթը։ NuGet Package Manager Console–ում պետք է գրել «Add-Migration InitialCreate -Context DataContext», որով ստեղծվում է InitialCreate բառարմատը պարունակող կլաս։ Հետագայում այդ կլասների հիման վրա ստեղծվելու են աղյուսակներ։ Պետք է ուշադրություն դարձնել, որ միգրացիոն պրոյեկտը ճիշտ ընտրված լինի։ Միգրացիոն ասեմբլին DbDomain պրոյեկտն է և պետք է ընտրել այն։

Բազան ստեղծելու համար միանգամից կարելի է գրել «Update-Database» հրամանը։ «Update-Database -Migration 0» հրամանով կարելի է ջնջել աղյուսակները, իսկ «Remove-Migration» ի – ով՝ միջրացիոն ֆայլերը։

Սերվերին ֆիզիկապես կապվելու համար կարելի է օգտվել կա՛մ SQL Server Object Explorer–ից, կա՛մ Server Explorer–ից։ Բացված պատուհանում պետք է լրացնել սերվերի անունը կամ դնել միջակետ։ Սերվերի անվանումը սահմանվում է SQL Server Management Studio–ի և SQL Server–ի տեղադռման ժամանակ։

Server Explorer — ի դեպքում կարող ենք ընտրել նաև անհրաժեշտ բազան։ Այս տարբերակն իմաստ ունի Database First մոտեցման դեպքում, երբ բազան արդեն նախապես ստեղծված է լինում։

Սերվերի անունը ճիշտ լրացնելու դեպքում թափվող ցուցակում երևալու են բոլոր բազաները։

Ինչպես երևում է սրեվերում ավելացել է «AutoPark» բազան, որում կա 2 աղյուսակ։ SQL Server Object Explorer–ի դեպքում երևում են այլ բազաներ ևս։

MVCPresentation պրոյետկտը պարունակում է Controller–ներ, որոնք Model–ի հիման վրա մշակում են ինֆորմացիան և փոխանցում View–ին։ Controller–ն անում է Get և Post հարցումներ։ Get–ը բազայից վերադարձնում է տվյալները, Post–ը՝ ուղարկում և պահում այնտեղ։ Controller–ն ավելացնում ենք այսպես։

Բազայի հաետ կապվելու համար գրել հետևյալ կոդը։

Բիզնես տրամաբանությունը և ինֆորմացիայի ներկայացումը պիտի լինեն առանձին, հետևաբար այդ 2 գործընթացների ժամանակ օգտագործվող մոդելները նույնպես պիտի առանձին լինեն։ MVCPresentation–ում պիտի ունենանք և օգտագործենք ViewModel, որը բազայի մոդելի մասնավոր դեպք է։ ViewModel–ում, օրինակ՝ կարող է չկիրառվել Id դաշտ, որովհետև օգտատերն այն ո՛չ ներմուծելու է, ո՛չ էլ՝ տեսնելու։

Controller–ի Create մեթոդը պետք է խմբագրել և ավելացնել LINQ հրահանգներ։

Lambda expression–ով HumanViewModel տիպի օբյետկից վերցնում ենք արժեք և վերագրում model–ի դաշտերին, որն էլ փոխանցվում է View–ին։ Քանի որ View–ի մեջ պետք է ցիկլի միջոցով ցույց տալ «model»–ի պարունակությունը, այն պեք է լինի Ienumerable տիպի։ Բոլոր մեթոնդերը պիտի ունենան View–ներ, որոնք կարող են ավտոմատ գենարացվել։ Մեր դեպքում Index մեթոդը նախատեսված է վերջնարդյունքը ցույց տալու համար, նրա կաղապարը պիտի լինի List, իսկ օգտագործվող մոդելը՝ HumanViewModel կլասը։ Նույն գործողությունները պետք է անել CarController կլասի համար։

Գենարացված կոդը ցույս է տալու աղյուսակ։ Կարող են արվել նաև որոշ փոփոխություններ։ Վերջնական տեսքը սա է՝

Model–ի item–ում պարունակվում են մարդու անունը, ազգանունը հասցեն, բնակավայրը և մեքենան։ Պետք է ուշադրություն դարձնել, որ մեքենայի դեպքում գրված է «item.Car.Model», ոչ թե ուղղակի «item.Car»։

Բայց նախ պետք է տվյալները ներմուծել։ Դրա համար օգտվում ենք Create մեթոդից, որը պարունակում է հետևյալ կոդը՝

DataContext — ի կամ որ նույնն է բազայի բազայի Humans աղյուսակում ավելացվում է հավաքածու, որը պարունակում է ներմուծված դաշտերի ինֆորմացիան։

Մեթոդի հիման վրա գեներացնում ենք կոդ։

Աշխատանքի արդյունքում ունենում ենք ներմուման հետյալ էջերը։

Կարելի է արդյունքը տեսնել և՛ բրաուզերում

Անմիջապես բազայում նույնպես կարելի է տեսնել տվյալների առկայությունը։ T–SQL հարցման կոդը՝

և դրա արդյունքը։

Բազայի հետ կապված աշխատանքի արագագործությունը մեծացնելու համար պետք է օգտվել ասինխրոնությունից։

«await» բառի շնորհիվ ամբողջ հարցումը կատարվում է առանձին թրեդում, իսկ այդ բառն օգտագործելու համար մեթոդը պիտի ունենա Task<T> վերադարձի տիպ և պարունակի «async» բառը։ Նույնն արվում է մյուս մեթոդների համար։

Ճարտարապաետության տեսանկյունից ավելի գրագետ մոտեցում է համարվում նման հարցումը Controller — ի փոխարեն, այլ, հատուկ այդ նպատակի համար նախատեսված Service–ներում անելը։

Օգտագործված սկզբնաղբյուրներ՝

1) Pro C# 9 with .NET 5, Foundational Principles and Practices in Programming, Andrew Troelsen

2) Complete guide to building an app with .Net Core and React — https://www.udemy.com/course/complete-guide-to-building-an-app-with-net-core-and-react/

Հարցերի դեպքում գտեք ինձ LinkedIn–ում, Instagram–ում, TikTok–ում և Facebook–ում։

--

--