(MVC) MVC (2017)

Entity Framework missing FAQ Part 1:

Entity Framework missing FAQ (Part 2).


3.1. Site with Project and without project (порівняння типів проєктів).


Це, друзі, продовження продовження першої частини моєї інтерпретації всесвітньо відомого прикладу ContosoUniversity. Я почну його с того, що спробую зробити проєкт у так званій проєктній архітектурі, тому що так зробили автори цього прикладу. Ну взагалі, ASP NET сайти можливо робити двома засобами - у проєктній та безпроєктній архітектурі. Особисто я, якщо це хоч якось можливо - я все роблю лише в безпроєктній, тому що код можно модифікувати без перезапуску проєкту. Це для мене головне, але багато людей бачить якісь переваги проєктної архітектури, я ці дурниці повторювати не буду. Тобто, ви можете створити сайт (ми поки що не говоримо про сайти для Linux на CORE або на XIMARIN, лише про ASP NET сайти для Windows) - їх можна зробити двома засобами. Або як окремий проєкт, або проєкт вбудований у солушен.



Приклад першої частини я зробив як безпроєктний. У цьому випадку солушен буде виглядати як планетка, окремого файла PRJ не буде, також у папці проєкту не буде вузла MyProject. Повних Property як у звичайному Class Library проєкті теж не буде (та це й непотрібно для сайту)



У проєктній архітектурі, секція проєкту буде присутня в окремому PRJ-файліку, буде присутні повні property від ClassLibrary проекту. Але головний DisAdvantage цього засобу будування ASP.NET сайтів - що досі не знаю, як можна міняти код проекту без перезапуску, тобто щоб працювала фонова компіляція VB-код. Therefore все інше для мене має жодного значення. Але щоб ви побачили різницю, я зробив продовження у not liked for me типу проекта.



Взагалі у цьому типи проєкту навіть звичайна отладка неможлива без хитрощів, наприклад у моему environment'і мені навіть потрібно знімати галку OnlyMyCode.



Зверніть увагу, друзі, що існує багато різних типів проєктів, не тільки безпроєктний або простий проєкт MVC, найбільш поширений проєкт зараз зовсім інший - WebApi. Але не будемо на цьому зупинятися, якщо цікаво, подивиться будь ласку цю сторінку - How classic ASP.NET programmers has realized WEB.API since 2005 year (eng).

Ну взагалі у ASP.NET багато чого можна робити по різному, я вже багато разів писав що у ASP.NET існує щонайменше 4,164,044,800,000,000 варіантів утворення сайтів по самому поверховому рахунку Variants of ASP NET Technology stack, кожен програмер нахвалює лише свій засіб, а для молодих програмерів характерно, що вони взагалі нічого у світі не бачили й рахують що те що вони знають - це й є єдиний засіб утворення сайтів. Але, друзі - почитайте скільки у мене проектів, от наприклад у 2016-му році я тільки описи зробив 20-ти проєктів Опис двадцяти моїх дрібних фрілансерских проєктів 2016-го року. - і у жодному з них середовище розробки не повторювало інше. Тому не дивуйтесь, що навіть автори цього всесвітньо відомого прикладу не змогли зробити цього на VB, бо в них виникли непереборні проблеми. Ну це ми трохи пішли у сторону, щоб ви зрозуміли, наскільки багато варіантів існує, не тільки проєктно-безпроєктно.


3.2. Стартовий MVC-project Contoso University in VB.


Отже тут буде трохи магії, яку не змогли перебороти автори цього прикладу, я законвертував їх проєкт у VB та додав туди логери EntityFramework. Це буде наш стартовий проєкт, з якого почнеться ця сторінка. Проєкт цей ви можете завантажити собі звідси ASP.NET Contoso University Code First start project in VB with Logger and Migration.zip

На що тут потрібно звернути увагу у цьому проєкті?


3.3. Attributes and Fluent API.


Цей проєкт має два типа утворення даних у базі - через атрибути, якось так:



   1:  Imports System.ComponentModel.DataAnnotations
   2:  Imports System.ComponentModel.DataAnnotations.Schema
   3:   
   4:  Namespace Models
   5:   
   6:      Public Class Department
   7:   
   8:          Public Property DepartmentID As Integer
   9:   
  10:          <StringLength(50, MinimumLength:=3)>
  11:          Public Property Name As String
  12:   
  13:          <DataType(DataType.Currency)>
  14:          <Column(TypeName:="money")>
  15:          Public Property Budget As Decimal
  16:   
  17:          <DataType(DataType.Date)>
  18:          <DisplayFormat(DataFormatString:="{0:yyyy-MM-dd}", ApplyFormatInEditMode:=True)>
  19:          <Display(Name:="Start Date")>
  20:          Public Property StartDate As DateTime
  21:   
  22:          Public Property InstructorID As Integer?
  23:   
  24:          <Timestamp>
  25:          Public Property RowVersion As Byte()
  26:   
  27:          Public Property Administrator As Instructor
  28:   
  29:          Public Property Courses As ICollection(Of Course)
  30:      End Class
  31:  End Namespace

Та через Fluent API, тобто ось так:



   1:  Imports System
   2:  Imports System.Data.Entity.Migrations
   3:  Imports Microsoft.VisualBasic
   4:   
   5:  Namespace Migrations
   6:      Public Partial Class InitialCreate
   7:          Inherits DbMigration
   8:      
   9:          Public Overrides Sub Up()
  10:              CreateTable(
  11:                  "dbo.CourseAssignment",
  12:                  Function(c) New With
  13:                      {
  14:                          .CourseID = c.Int(nullable := False),
  15:                          .InstructorID = c.Int(nullable := False)
  16:                      }) _
  17:                  .PrimaryKey(Function(t) New With { t.CourseID, t.InstructorID }) _
  18:                  .ForeignKey("dbo.Course", Function(t) t.CourseID, cascadeDelete := True) _
  19:                  .ForeignKey("dbo.Instructor", Function(t) t.InstructorID) _
  20:                  .Index(Function(t) t.CourseID) _
  21:                  .Index(Function(t) t.InstructorID)
  22:  ...

More about attributes Use attribute for custom validation function, Use jQuery Unobtrusive Validation, custom attributes for validation and validation service/controller, Use CustomAttribute to store metadata about model field, Use UIHint attribute to define template for EditorFor and DisplayFor helpers.



3.4. Перелік атрибутів Data Annotations.


Атрибути - це маркери методів або класів, їх вичитують якись проги як дані за допомогою рефлекшен. Я так тоже роблю майже у всіх своїх проєктах, ось наприклад тут - Аналіз MVC-сайту за допомогою System.Reflection Атрибутів. Це дозволяє уникнути специфічних назв класів, наприклад HomeController та використовувати які завгодно імена, з одного боку. А з іншого боку дозволяє скоротити код, тобто не писати кожного разу перевірку довжини поля, наприклад, а просто записати поруч з текстовим полем валідатор довжини, до того ж, ASP.NET побудований так, що ці довжина буде перевірятися не тільки на сервері, а й у браузері (що дуже корисно).

Можна зробити самостійно тестову валідацію у окремому консольному проєкті ось так. До речі неважко додати й свої власні атрибути та використовувати їх якось у своїх прогах. Але мікрософтовські індуси вже додали 20-30 найбільш поширених атрибутів, яки читаються как валідаторами, так і самою студією (наприклад Scafford плагіном), так і кодом EF.



Їх непогано було б поділити на декілька категорій, залежно від того, якою саме прогою вони читаються (EF, клієнтським валідатором, VS або іншими). Але це не так просто, бо деякі атрибути читаются різними прогами, а по друге я навіть не знайшов офіційний перелік ціх атрибутів. Перелік нище неточний, бо я його зробив за 10 секунд. Повний перелік знаходиться нище - 3.6 Close look to controller code.

Саме ці DataAnnotation дозволяють утворити достатньо складний код за один клік мишкою.




3.5. Scaffold template and custom scaffold template.


Scaffold template - це найпростіший засіб отримати хоч якусь економію часу та автоматично отримати код контролеру та форм для найпростіших CRUD операцій. Тобто для CreateUpdateDelete для найпростіших табличок-довідників. Це задачка з абетки, наприклад мені кожного разу ії сують на тестах Декілька моїх останніх тестових проєктів., але найбільш цікаво те, що у реальних проєктах, мені здається, що не більше 10% процентів форм можливо побудувати таким чином. Я ось навмисно узяв і проаналізував пару своїх великих MVC проектів, от наприклад тут Электронный магазин запчастей SHEL-AUTO.RU на web-сервисах EMEX.RU можливо побудувати усього дві форми з біля 200, усі інші форми набагато складніші. Ось тут Social network for Canada with printed version of calendar to communities можна у адмінці всі прості форми побудувати за допомогою цього мастера, тобто не меньш 10% форм. Ось тут Проекты нового Вотпуска їх взагалі неможна використати, бо немає табличок з ключами у вигляді простих цілих, що вимагає для роботи EF, ось тут SPA-page на Classic ASP.NET та jQuery. потрібні ті ж самі CRUD-операції, але у вигляді SPA-сторінок. Тобто я хочу вас застережити від індуської реклами - так, існує такий метод автогенерації кода як Scaffold - але я не впевнений, що його можна застосувати хоч до 10% форм у реальних проєктах.

До речі, одна з найпоширених задач фрілансу, коли індуси "знімають пенку", тобто роблять щось подібне до проєкту саме за допомогою найпростіших Scaffold-автогенераторів, а потім соскакують з проєкту. А мене було безліч подібних проєктів, пару я навіть записав. Ось наприклад такий фрагмент My project for Nairobi, Kenya (ASP.NET Classic, VB.NET, NET 4.5, Bootstrap, Entity Framework) - індуси зробили найпростіші автогенеровані сторінки, а далі ії потрібно було ускладнювати та переробляти на Bootstrap. Тут немає автогенерації, це потрібно багато днів ручками стрічку за стрічкою переробляти ручками - з такої роботи індуси відразу морозяться і недороблений сайт попадає на фріланс. Тобто пенки з нього вже зняли, 80% процентів грошей власник проєкту вже заплатив за перший день роботи над проєктом, але проєкт після першого дня готовий фактично лише на 1% та уявляє з себе не більш ніж автоенеровані форми, які ще налаштовувати та налаштовувати (може не один місяць) - а грошей у проєкті вже немає. До речі, існує технология власних автогенераторів Creating a Custom Scaffolder for Visual Studio, такі речі як форми на Boostrap у проєкті, що на відео, мабуть простіше було б спочатку зробити власний автогенератор, ніж переробляти стандартний автогенерирований код. Крім того, існуючий автогенератор можна налаштовувати за допомогою макросів T4 How to customize the generated files from the New Scaffolded . Нажаль, поки що у мене не було проєктів, де налаштування автогенератора або власні автогенератори були в економічно обґрунтовані. Ну може тому, що (як я казав вище) у комерційних проєктах взагалі існує не так багато таких простих форм, які можна зробити автогенератором.

Інша цікава особливість цього метода автогенераціЇ кода, що він потребує повністю цілісної моделі даних, тобто він перевіряє всю модель, а не одну табличку, яку вам потрібно. Тобто ви повинні сама атрибутами побудувати повністю коректну модель, якщо це не так, то ви навіть для найменш важливого свого довідника не отримуєте автогенерацію кода. Тобто для цієї сторінки я взяв код с прикладу ContosoUneversity, і просто зробив конвертацію C# у VB, ніяк не змінюючи базу та відносини між табличками. Але навіть форму для студентів я не зміг отримати автоматично, поки не змінив схему у зовсім іншому місці, ніяк з студентами не пов'язаною.



Але якщо ви розібралися з застосуванням усіх атрибутів, правильно побудували усі відносини 1:1, 1:M, M:M між табличками, то далі все буде просто - цей мастер вам утворить код автоматично.




3.6. Close look to controller code.


Якщо, друзі, ви подивитесь на код контролеру, то по перше він теж насичений атрибутами. Що взагалі означає бути MVC-програмістом? Це означати пам'ятати більшість цих класів, їх методів, розуміти їх призначення, та коректно їх використовувати.





3.7. Виготовлення власних Extension-хелперов.


Ця ремарка, як и наступна, стосується взагалі програмування MVC. Існують так звані Extension-функції, це такий цікавий викидень обьектного програмування, коли ви можете додавати у класі-потомці свою власну функції до статичного блока функцій базового класу і якщо ви зробили імпорт вашої extension-функції, то можете неї користуватися у будь якому місці. Extension-функції також мають цікавий сінтаксіс, тобто перший параметр у них - це клас який ви поширюєте. У мене на сайті опублікована безліч різноманітних функцій - ви можете побачити як вини пишуться - наприклад Змінні Nullable та як обробляти DBNull з бази за допомогою Extension-функції, Мої поширення Linq-to-SQL, How to reorder DataRow with Extension function, Anonymous types, Lambda Expression and Linq Special Row Comparer (eng), Expanding opportunities of Classic ASP.NET with generic extension function FindBaseClassRecursively (eng), Amazing extension function CopyLinqDataMembersByName to expand Linq-to-SQL (eng). Мені ці можливість подобається і їх пишу достатньо часто.

У MVC існує немало стандартних Extension хелперов.



Але найбільш корисно, як мабуть ви вже зрозуміли, є написання власних хелперов. Це мабуть трохи теж саме ніж власні scafford-template, але на молекулярному рівні. How to create Razor html-helper in VB.NET, Define common code as Function and Helpers (directly in View and in the codeBehind).


3.8. Store data in ViewState/ViewBag/ViewData/TempData


Ще одна найважливіша річ, без якої неможливо зробити навіть найпростіший сайт - це яким чином зберігати дані, які передаються на форму - та як передати дані на сервері між різними класами (наприклад класом, що рендеріть форму та класом контролеру). Сама назва MVC (Model-View-Controller) має на увазі дані, які у формі Model виготовляються контролером та передаються у View для демонстрації у відформатованому вигляді.

Тут є важливий додаток, як Web-сервер зв'язує кожного користувача сайта з його власними даними. Звичайно це робиться за допомогою куків ASPNETSESSIONID, які ви можете бачити у будь якому сайті ASP.NET. Але так буває не завжди, конкретні дані з юзером можуть зв'язуватися також за допомогою Session-сервера. Такий засіб у мене використовуються наприклад на порталі http://votpusk.ru, тобто залогінівшись у один сайт порталу ви опиняєтесь залогіненим у всіх сайтах порталу. Але й це лише інший, другий засів пов'язування користувачів сайту з його даними. Найбільш просунутий, який звичайно використовується у кластерах, коли десятки web-серверів обслуговують юзерів синхронно - це засіб пов'язування за допомогою SQL-сервера. У цьому році у мені як раз був такий проєкт, коли я якимось індусам пов'язав у кластер десяток серверів, ось тут налаштування такого зв'язку Transfer session between ASP.NET apps by SQL-server.

Але зв'язок користувача сайта з його власними сессіоними даними - це одне питання, а інше питання, у якоми вигляді зберігати дані та передавати їх на сервері між класами. Тут існує сім головних засобів.

More - Save ModelState with Redirection.

More - https://www.c-sharpcorner.com/blogs/viewdata-vs-viewbag-vs-tempdata-in-mvc1




Entity Framework missing FAQ Part 3:



Comments ( )
Link to this page: //www.vb-net.com/EF-missing-FAQ/index2.htm
< THANKS ME>