Мы продолжаем разработку нашего SPA приложение (или single page application).
Теперь пришло время создать реальную базу данных.
Наша база будет реализована на основе ORM системы, которая обеспецивает невернятно гибкую и очень быструю работу с данными
Для начала нам нужно установить два удобных для рабты фрэймворка. entity framework core и ASP.NET Core Identity.
ASP.NET Core Identity – мощная система авторизации от Microsoft, которая уже включает в себя всё необходимое для регистрации пользователей и их авторизации. Однако для храненния данных о пользователях, их пароли и т.п. нам необоходима база данных. Поэтому Identity Framework устроет на основе Entity framework-а. Самое крутое в этой системе что она использует атрибуты C#. Т.е. нам не надо писать код на подобие
1
2
3
|
If(not Authorized)
//Bla bla bla…
Endif;
|
Реальный пример врйэмфорка Yii2 php. Это не значит, что Yii2 или php хуже просто инфраструктура языка c# значительно более мощная и гибкая. Собственно, эта гибкость позволяет нам реализовать простую задачу проще.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
|
class UserGroupRule extends Rule
{
public $name = ‘userGroup’;
public function execute($user, $item, $params)
{
if (!Yii::$app->user->isGuest) {
$group = Yii::$app->user->identity->group;
if ($item->name === ‘admin’) {
return $group == 1;
} elseif ($item->name === ‘author’) {
return $group == 1 || $group == 2;
}
}
return false;
}
}
|
В Identity framework core Всё что нам нужно сделать это атрибутировать класс, метод или свойство атрибутом [Authorize]. Но и конечно нам ничто не мешает сделать проверку авторизованного пользователя через конструкцию if.
1
2
3
4
5
6
7
8
|
[Authorize]
public class AccountController : ApiController
{
public async Task<IHttpActionResult> Register([FromBody] string params)
{
//
}
}
|
entity framework core в свою очередь это мощнейший механизм взаимодействия с базой на уровне объектов. Entity переводится как сущность. Сущность — это просто одна запись в таблице базы данных. Например, таблица «пользовать» содержит множество сущностей пользователей. Такую систему взаимодействие объектов-сущностей в коде называют ORM (Object-Relational Mapping, рус. объектно-реляционное отображение) (показать вики). Entity framework core – это готовая ORM От Microsoft.
Преимущество ORM
Например, без ORM, чтобы сделать обычный запрос к базе и перебрать данные в цикле. Нужно использовать сложную конструкцию.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
|
private void AdoNetExample()
{
string connectionString =
@«Data Source=(local);Initial Catalog=Northwind;Integrated Security=true»;
string queryString =
@«SELECT ProductID, UnitPrice, ProductName from dbo.products
WHERE UnitPrice > @pricePoint
ORDER BY UnitPrice DESC;»;
int paramValue = 5;
var products = new List<Product>();
using (SqlConnection connection = new SqlConnection(connectionString))
{
SqlCommand command = new SqlCommand(queryString, connection);
command.Parameters.AddWithValue(«@pricePoint», paramValue);
try
{
if (connection.State == ConnectionState.Closed) connection.Open();
SqlDataReader reader = command.ExecuteReader();
while (reader.Read())
{
products.Add(new Product
{
ProductId = reader.GetInt32(0),
ProductName = !reader.IsDBNull(1) ? reader.GetString(1) : string.Empty,
UnitPrice = !reader.IsDBNull(2) ? reader.GetDouble(2) : 0
});
}
reader.Close();
}
catch (Exception ex)
{
Console.WriteLine(ex.Message);
}
}
foreach (var p in products)
{
Console.WriteLine(«\t{0}\t{1}\t{2}», p.ProductId, p.ProductName, p.UnitPrice);
}
Console.ReadLine();
}
|
С entity framework это значительно проще и изящнее.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
|
private void EntityExample()
{
string connectionString =
@«Data Source=(local);Initial Catalog=Northwind;Integrated Security=true»;
var ctx = new DbContext(connectionString);
int paramValue = 5;
var products = ctx.Products
.Where(p => p.UnitPrice > paramValue)
.OrderByDescending(p => p.UnitPrice)
.ToList();
foreach (var p in products)
{
Console.WriteLine(«\t{0}\t{1}\t{2}», p.ProductId, p.ProductName, p.UnitPrice);
}
Console.ReadLine();
}
|
Т.к. мы с вами очень разумны и не хотим писать километровые инструкции для вызова лишь одной таблицы, то мы конечно будем использовать ORM entity framework core.
Итак, давайте установим базу в наш проект. Важно отметить что так как авторизация пользователей требует также наличие базы, то сам Identity framework по умолчанию запускается на основе Entity framework. Давайте установим ASP.NET Core Identity.
Запустим NuGet и добавим несколько пакетов
Моя текущая структура зависимостей
Необходимо установить следующие зависимости:
Microsoft.Aspnetcore.Identity
Microsoft.Aspnetcore.Identity.entityframeworkcore
Microsoft.EntityFrameworkCore.SqlServer
Microsoft.EntityFrameworkCore.Design
Microsoft.EntityFrameworkCore.Tools
Нажмитие правой кнопкой по проекту и выбирите пункт “Manage NuGet packages” перейдите во кладку brows и наберите соответсвующие звисимости.
Теперь в корень проекта добавим папку Models и внутри папки добавим наш класс контекста. WebApiDbContext. Необходимо раширить наш класс классом фреймворка IdentityDbContext. Всё что вам необходимо сделать это добавить данную констукцию. К тому же нам необходимо добавить конструктор, который принимает параметры с типом DbContextOptions<WebapiDbContext> это просто стандартная настройка фрэймворка её можно запомнить или просто взять из документации.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
|
using Microsoft.AspNetCore.Identity.EntityFrameworkCore;
using Microsoft.EntityFrameworkCore;
namespace WebApiApplication.Models
{
public class WebapiDbContext : IdentityDbContext
{
public WebapiDbContext(DbContextOptions<WebapiDbContext> options)
:base(options)
{
}
}
}
|
В классе startup.cs нам нужно реализовать строку подключения и настроить зависимости. Поэтому для начала добавим строку подключения. Как вы догадались у меня уже установленна база данных MS SQL server, поэтому мне просто нужно набрать строку подключения.
1
|
public const string CONNECTION_STRING = «Data Source=localhost; Initial Catalog=WebApiDbContext;Integrated Security=True»;
|
В методе ConfigureServices класса Startup.cs добавим настройку entity и identity фрэймворков.
1
2
3
4
5
|
services.AddDbContext<WebapiDbContext>(options => options.UseSqlServer(CONNECTION_STRING));
services.AddIdentity<IdentityUser, IdentityRole>()
.AddEntityFrameworkStores<WebApiDbContext>()
.AddDefaultTokenProviders();
|
Еще раз обратите внимание на строку подключения в сегменте initial catalog название нашей будущей базы. Сейчас её нет.
Дело в том, что фрэймворт создаст её автоматически.
После всех настроек теперь можно запустить миграцию. Если вкратце миграции — это мощный способ создавать таблицы на основе нашего кода без необходимости редактировать саму базу через, например Management studio или создавать таблицы через sql запросы. Система сама сравнивает наш контекст и создает на основе этого контекста таблицы или сущности.
Т.к. мы унаследовались от класса IdentityDbCOntext то данный контекст уже содержит сущность. В этом можно убедиться если посмотреть базового потомка класса IdentityDbContext нажав клавишу F12 или правой кнопкой мыши –> “перейти к определению”.
Давайте перейдем к определению к самому первому потомку. И уже внутри него мы наконец увидим наши будущие таблицы
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
|
//
// Сводка:
// Gets or sets the Microsoft.EntityFrameworkCore.DbSet`1 of Users.
public DbSet<TUser> Users { get; set; }
//
// Сводка:
// Gets or sets the Microsoft.EntityFrameworkCore.DbSet`1 of User claims.
public DbSet<TUserClaim> UserClaims { get; set; }
//
// Сводка:
// Gets or sets the Microsoft.EntityFrameworkCore.DbSet`1 of User logins.
public DbSet<TUserLogin> UserLogins { get; set; }
//
// Сводка:
// Gets or sets the Microsoft.EntityFrameworkCore.DbSet`1 of User roles.
public DbSet<TUserRole> UserRoles { get; set; }
//
// Сводка:
// Gets or sets the Microsoft.EntityFrameworkCore.DbSet`1 of User tokens.
public DbSet<TUserToken> UserTokens { get; set; }
//
// Сводка:
// Gets or sets the Microsoft.EntityFrameworkCore.DbSet`1 of roles.
public DbSet<TRole> Roles { get; set; }
//
// Сводка:
// Gets or sets the Microsoft.EntityFrameworkCore.DbSet`1 of role claims.
public DbSet<TRoleClaim> RoleClaims { get; set; }
|
На основе вот эти данных система сформирует таблицы в базе. Чтобы убедится в этом добавим миграцию.
Откройте «Вид» -> «Другие окна» -> «Консоль диспетчера пакетов» наберите слово Add- и нажмите «Tab» появится подсказка. Если подсказки нет, то скорее всего вы не установили пакет Microsoft.EntityFrameworkCore.Tools. Если всё хорошо выберем Add-Migration и добавим какое-нибудь своё название, например, InitialDb и нажмем Enter.
1
|
Add—Migration InitialDb
|
У нас появится сконфигурированный для создания базы и таблиц файл миграции. На этом этапе базы еще нет. Потому что мы не запустили миграцию. Чтобы это сделать наберите команду Update-Database и нажмите Enter.
Проверим базу данных, создалась ли она
Подключимся к базе через VisualStudio на вкладке «вид» –> «обозреватель серверов».
Вы выпадающем списке как раз и будет наша новая база «WebApiDbContext»
Раскройте список и посмотрите какие таблицы добавила система.
Спасибо!)