|
@@ -0,0 +1,115 @@
|
|
|
|
|
+# Модели
|
|
|
|
|
+
|
|
|
|
|
+## Введение в определение и применение моделей
|
|
|
|
|
+
|
|
|
|
|
+Одним из ключевых компонентов паттерна MVC являются __модели__. Ключевая задача моделей - описание структуры и логики используемых данных.
|
|
|
|
|
+
|
|
|
|
|
+Как правило, все используемые сущности в приложении выделяются в отдельные модели, которые и описывают структуру каждой сущности. В зависимости от задач и предметной области мы можем выделить различное количество моделей в приложении.
|
|
|
|
|
+
|
|
|
|
|
+Все модели оформляются как обычные POCO-классы (plain-old CRL objects), то есть обычные классы на языке C#. Например, если мы работаем с данными пользователей, то мы могли бы определить в проекте следующую модель, которая представляет пользователя:
|
|
|
|
|
+
|
|
|
|
|
+```cs
|
|
|
|
|
+public class Person
|
|
|
|
|
+{
|
|
|
|
|
+ public int Id { get; set; }
|
|
|
|
|
+ public string Name { get; set; } = "";
|
|
|
|
|
+ public int Age { get; set; }
|
|
|
|
|
+}
|
|
|
|
|
+```
|
|
|
|
|
+
|
|
|
|
|
+Модель Person определяет ряд свойств: уникальный идентификатор _Id_, _имя_ и _возраст_ пользователя. Это классическая анемичная модель. Анемичная модель не имеет поведения и хранит только состояние в виде свойств.
|
|
|
|
|
+
|
|
|
|
|
+В языке C# для представления подобных моделей удобно использовать классы __record__:
|
|
|
|
|
+
|
|
|
|
|
+```cs
|
|
|
|
|
+public record class Person(int Id, string Name, int Age);
|
|
|
|
|
+```
|
|
|
|
|
+
|
|
|
|
|
+Однако модель необязательно должна состоять только из свойств. Кроме того, она может иметь конструктор, какие-нибудь методы, поля, вообщем предствлять стандартный класс на языке C#. Модели, которые также определяют поведение, в противоположность анемичным моделям называют "толстыми" моделями (Rich Domain Model / Fat Model / Thick Model). Например, мы можем уйти от анемичной модели, добавив к ней какое-нибудь поведение:
|
|
|
|
|
+
|
|
|
|
|
+```cs
|
|
|
|
|
+public class Person
|
|
|
|
|
+{
|
|
|
|
|
+ public int Id { get; set; }
|
|
|
|
|
+ public string Name { get; set; }
|
|
|
|
|
+ public int Age { get; set; }
|
|
|
|
|
+ public Person(int id, string name, int age)
|
|
|
|
|
+ {
|
|
|
|
|
+ Id = id;
|
|
|
|
|
+ Name = name;
|
|
|
|
|
+ Age = age;
|
|
|
|
|
+ }
|
|
|
|
|
+ public string PrintInfo() => $"{Id}. {Name} ({Age})";
|
|
|
|
|
+}
|
|
|
|
|
+```
|
|
|
|
|
+
|
|
|
|
|
+В приложении ASP.NET MVC Core модели можно разделить по степени применения на несколько групп:
|
|
|
|
|
+
|
|
|
|
|
+- Модели, объекты которых хранятся в специальных хранилищах данных (например, в базах данных, файлах xml и т.д.)
|
|
|
|
|
+- Модели, которые используются для передачи данных представление или наоборот, для получения данных из представления. Такие модели еще называтся моделями представления
|
|
|
|
|
+- Вспомогательные модели для промежуточных вычислений
|
|
|
|
|
+
|
|
|
|
|
+Как правило, для хранения моделей создается в проекте отдельная папка `Models`. Модели представления нередко помещаются в отдельную папку, которая нередко называется `ViewModels`. В реальности, это могут быть каталоги с любыми называниями, можно помещать модели хоть в корень проекта, но более распространенным стилем являются названия `Models` и `ViewModels`.
|
|
|
|
|
+
|
|
|
|
|
+Например, создадим новый проект ASP.NET Core. Добавим в него папку `Models`, в которую добавим новый класс __Person__
|
|
|
|
|
+
|
|
|
|
|
+```cs
|
|
|
|
|
+namespace MvcApp.Models
|
|
|
|
|
+{
|
|
|
|
|
+ public record class Person(int Id, string Name, int Age);
|
|
|
|
|
+}
|
|
|
|
|
+```
|
|
|
|
|
+
|
|
|
|
|
+Эта модель будет описывать данные, которые мы будем использовать. Эти данные могли бы храниться в базе данных, но для простоты мы определим их в контроллере.
|
|
|
|
|
+
|
|
|
|
|
+Далее добавим в проект папку ``Controllers``, а в нее новый класс - __HomeController__ со следующим кодом:
|
|
|
|
|
+
|
|
|
|
|
+```cs
|
|
|
|
|
+using Microsoft.AspNetCore.Mvc;
|
|
|
|
|
+using MvcApp.Models; // пространство имен модели Person
|
|
|
|
|
+
|
|
|
|
|
+namespace MvcApp.Controllers
|
|
|
|
|
+{
|
|
|
|
|
+ public class HomeController : Controller
|
|
|
|
|
+ {
|
|
|
|
|
+ List<Person> people = new List<Person>
|
|
|
|
|
+ {
|
|
|
|
|
+ new Person(1, "Tom", 37),
|
|
|
|
|
+ new Person(2, "Bob", 41),
|
|
|
|
|
+ new Person(3, "Sam", 28)
|
|
|
|
|
+ };
|
|
|
|
|
+ public IActionResult Index()
|
|
|
|
|
+ {
|
|
|
|
|
+ return View(people);
|
|
|
|
|
+ }
|
|
|
|
|
+ }
|
|
|
|
|
+}
|
|
|
|
|
+```
|
|
|
|
|
+
|
|
|
|
|
+Список объектов модели __Person__ передается в представление с помощью метода _View()_.
|
|
|
|
|
+
|
|
|
|
|
+И в конце добавим в проект папку `Views`, а в нее - каталог `Home`. Далее в папку `Views/Home` добавим представление `Index.cshtml`, которое будет выводить все объекты:
|
|
|
|
|
+
|
|
|
|
|
+```cshtml
|
|
|
|
|
+@using MvcApp.Models
|
|
|
|
|
+@model IEnumerable<Person>
|
|
|
|
|
+
|
|
|
|
|
+<h2>People</h2>
|
|
|
|
|
+<table class="table">
|
|
|
|
|
+ <th>
|
|
|
|
|
+ <td>Id</td>
|
|
|
|
|
+ <td>Name</td>
|
|
|
|
|
+ <td>Age</td>
|
|
|
|
|
+ </th>
|
|
|
|
|
+ @foreach (var p in Model)
|
|
|
|
|
+ {
|
|
|
|
|
+ <tr>
|
|
|
|
|
+ <td>@p.Id</td>
|
|
|
|
|
+ <td>@p.Name</td>
|
|
|
|
|
+ <td>@p.Age</td>
|
|
|
|
|
+ </tr>
|
|
|
|
|
+ }
|
|
|
|
|
+</table>
|
|
|
|
|
+```
|
|
|
|
|
+
|
|
|
|
|
+
|