Доступ к данным в .NET MAUI. Миграции EF Core в .NET MAUI

Одной из замечательных возможностей EF Core является использование миграций — обновления структуры БД без потери данных. Миграции EF Core в .NET MAUI используются с некоторыми различиями по сравнению с другими типами проектов. В этой части мы рассмотрим как создавать и использовать миграции EF Core в .NET MAUI

Миграции EF Core в .NET MAUI

Подготовка проекта .NET MAUI для работы с миграциями

В качестве примара проекта, демонстрирующего миграции EF Core в .NET MAUI мы будем использовать проект из предыдущей части. На данный момент в этом проекте имеется контекст базы данных, который выглядит следующим образом:

public class ApplicationContext : DbContext
{
    public DbSet<Project> Projects { get; set; }

    public ApplicationContext(DbContextOptions<ApplicationContext> options) : base(options)
    {
        Database.EnsureDeleted();
        Database.EnsureCreated();
    }
}

То есть, каждый раз как только мы пытаемся получить доступ к контексту БД, файл базы данных пересоздается заново. Для отладки проекта такой подход вполне допустим, однако, если мы развиваем уже существующий проект, то в этом случае мы можем потерять данные, что не всегда допустимо. Поэтому в этом случае лучше использовать миграции.

Чтобы использовать Миграции EF Core в .NET MAUI необходимо добавить в проект NuGet  Microsoft.EntityFrameworkCore.Tools

Если вы планируете применять миграции при запросе контекста базы данных, то необходимо изменить конструктор класса ApplicationContext следующим образом:

public ApplicationContext(DbContextOptions<ApplicationContext> options) : base(options)
{
    //Database.EnsureDeleted();
    //Database.EnsureCreated();
    Database.Migrate();
}

Теперь наше приложение сможет использовать миграции. Однако, при попытке выполнить команду на создание миграции вы столкнетесь со следующей ошибкой:

Startup project ‘MauiEfCore’ targets platform ‘Android’. The Entity Framework Core Package Manager Console Tools don’t support this platform. See https://aka.ms/efcore-docs-pmc-tfms for more information.

Такая ошибка будет возникать даже, если вы собираете приложение под Windows. Это и есть то самое отличие использования Миграции EF Core в .NET MAUI по сравнению с другими проектами .NET. Чтобы обойти это ограничение, нам необходимо создать фиктивный проект (не .NET MAUI), который будет использоваться нами только для создания и применения миграций в нашем приложении .NET MAUI.

Так как далее мы будем использовать для работы с миграциями обычное консольное приложение, то, чтобы не подключать лишние пакеты в консольное приложение, немного изменим конструктор контекста базы данных и переопределим метод OnConfiguring() следующим образом:

public class ApplicationContext : DbContext
{
    public DbSet<Project> Projects { get; set; }


    protected override void OnConfiguring(DbContextOptionsBuilder optionsBuilder)
    {
        base.OnConfiguring(optionsBuilder);
        optionsBuilder.UseSqlite("Data Source=databse.dat");
    }

    public ApplicationContext() : base()
    {
        //Database.EnsureDeleted();
        //Database.EnsureCreated();
        Database.Migrate();
    }
}

Также изменим регистрацию сервиса в приложении:

builder.Services.AddDbContext<ApplicationContext>();

Теперь приступим к изменению нашего решения для того, чтобы использовать миграции в EF Core и .NET MAUI

Создание фиктивного проекта для использования миграций в .NET MAUI

Так как и наше приложение .NET MAUI и новый проект будут использовать одну и ту же модель данных и контекст базы данных, то имеет смысл разделить наш проект на части.

Библиотека классов

Во-первых, создадим новый проект библиотеки классов:

Назовем его MauiEfCore.Models. Этот проект будет хранить модель данных. На данный момент, у нас в качестве модели выступает всего один класс — Project. Поэтому перенесем его в новый проект:

Так как теперь наша модель находится в другой сборке, то не забываем подключить эту сборку к нашему основному проекту и изменить пространство имен. Для этого добавим ссылку на проект MauiEfCore.Models в наш основной проект

Теперь перейдем в файл MainPage.xaml проекта и изменим подключение пространства имен MauiEfCore.Models следующим образом:

xmlns:models="clr-namespace:MauiEfCore.Models;assembly=MauiEfCore.Models"

Открывающий тег для страницы теперь должен выглядеть следующим образом:

<ContentPage xmlns="http://schemas.microsoft.com/dotnet/2021/maui"
             xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
             x:Class="MauiEfCore.MainPage"
             xmlns:local="clr-namespace:MauiEfCore.ViewModels"
             xmlns:models="clr-namespace:MauiEfCore.Models;assembly=MauiEfCore.Models"
             x:DataType="local:MainPageViewModel">

Можно проверить приложение и убедиться, что оно работает также, как и ранее. Перейдем к следующей части — создадим проект с необходимыми для работы приложений сервисами.

Проект для сервисов

Добавим в решение новый проект библиотеки классов, как и выше, и назовем его MauiEfCore.Services. В эту библиотеку мы поместим контекст базы данных. Также, для этого проекта добавим ссылку на библиотеку с моделями. Должно получиться вот так:

Так как в этом проекте используется контекст базы данных, то необходимо добавить необходимые NuGet-пакеты:

В основной проект также не забываем подключить эту библиотеку:

Осталось добавить фиктивный проект.

Фиктивный проект для миграций

Добавим в решение обычное консольное приложение, которое назовем FakeApp. В этот проект нам необходимо добавить обе библиотеку классов:

Миграции EF Core в .NET MAUIКод приложения будет минимальным:

using MauiEfCore.Services;

ApplicationContext context = new ApplicationContext();

На этом все подготовительные операции закончены. Можно приступать к созданию и применению миграций.

Миграции EF Core в .NET MAUI. Использование миграций

Теперь, чтобы создать миграцию нам необходимо перейти в диспетчер пакетов и выполнить следующую операцию:

Add-Migration InitialCreate -project MauiEfCore.Services -startupproject FakeApp

здесь

  • InitialCreate — имя новой миграции
  • -project MauiEfCore.Services — проект, содержащий контекст БД
  • -startupproject FakeApp — запускаемый проект

После выполнения этой операции вы увидите, что в библиотеке MauiEfCore.Services появится папка, содержащая новую миграцию:

Миграции EF Core в .NET MAUI

Теперь можно запустить наш основной проект и убедиться, что всё работает как и прежде, но только теперь мы можем создавать и применять миграции. Сейчас в нашем классе ApplicationContext миграции применяются при создании класса:

public ApplicationContext() : base()
{
    Database.Migrate();
}

При создании новой миграции вы можете столкнуться с такой ошибкой:

Unable to create a ‘DbContext’ of type ‘RuntimeType’. The exception ‘An error was generated for warning ‘Microsoft.EntityFrameworkCore.Migrations.PendingModelChangesWarning’: The model for context ‘ApplicationContext’ has pending changes. Add a new migration before updating the database. See https://aka.ms/efcore-docs-pending-changes. This exception can be suppressed or logged by passing event ID ‘RelationalEventId.PendingModelChangesWarning’ to the ‘ConfigureWarnings’ method in ‘DbContext.OnConfiguring’ or ‘AddDbContext’.’ was thrown while attempting to create an instance. For the different patterns supported at design time, see https://go.microsoft.com/fwlink/?linkid=851728

Чтобы избавиться от этой ошибки, перед созданием новой миграции просто закомментируйте эту строку:

Database.Migrate();

Итого

Миграции EF Core в .NET MAUI можно создать, если использовать специальный фиктивный проект, например, обычное консольное приложение, которое будет выполнять одну простую задачу — создавать контекст базы данных при запуске миграции. Для этого желательно разделить основной проект .NET MAUI и выделить библиотеку моделей и библиотеку сервисов, которые будут подключаться в оба проекта — основной и фиктивный. Библиотеку сервисов и библиотеку моделей, при необходимости, можно совместить в один проект, однако, при большом количестве сервисов и моделей такой проект, возможно, будет тяжело поддерживать.

Подписаться
Уведомить о
guest
0 Комментарий
Старые
Новые Популярные
Межтекстовые Отзывы
Посмотреть все комментарии