Миграция из базы данных сначала для кодирования первой модели с использованием идентификатора с использованием ASP.NET Core и MySQL
Я давно занимаюсь разработкой сайта. Недавно я понял, что мне понадобится модель идентификации (с использованием встроенной функциональности ASP.NET), так как я хотел бы сначала преобразовать модель базы данных в код.
Теперь я понимаю, что это довольно резкое изменение в структуре, но, тем не менее, я предполагаю, что это должно быть возможно.
СОСТАВ
Я подготовил следующие пакеты для подготовки к миграции и конвертации:
"Microsoft.AspNetCore.Identity": "1.0.0",
"Microsoft.AspNetCore.Identity.EntityFrameworkCore": "1.0.0",
"SapientGuardian.EntityFrameworkCore.MySql": "7.1.4",
"Microsoft.EntityFrameworkCore.Tools": {
"version": "1.0.0-preview2-final",
"type": "build"
},
"Microsoft.AspNetCore.Diagnostics.EntityFrameworkCore": "1.0.0",
"Microsoft.AspNetCore.Authentication.Cookies": "1.0.0"
Это то, что я считаю обязательным для этого (различные статьи, посты в блогах и тому подобное).
Отсюда я настраивал свой контекст DatabaseContext
, как это:
public class DatabaseContext : IdentityDbContext<User>
{
public DatabaseContext(DbContextOptions<DatabaseContext> options)
:base(options)
{ }
protected override void OnModelCreating(ModelBuilder builder)
{
base.OnModelCreating(builder);
<!-- I'm not interested in using all IdentityUser properties, hence ignoring those not needed -->
builder.Entity<User>().ToTable("Users")
.Ignore(x => x.ConcurrencyStamp)
.Ignore(x => x.LockoutEnabled)
.Ignore(x => x.LockoutEnd)
.Ignore(x => x.NormalizedEmail)
.Ignore(x => x.NormalizedUserName)
.Ignore(x => x.PhoneNumber)
.Ignore(x => x.PhoneNumberConfirmed)
.Ignore(x => x.TwoFactorEnabled);
<!-- Again, ignoring the properties I do not want from IdentityRole -->
builder.Entity<IdentityRole>().ToTable("Roles")
.Ignore(x => x.ConcurrencyStamp)
.Ignore(x => x.NormalizedName);
<!-- Adding the rest of the identity models, and mapping these into their correct database table -->
builder.Entity<IdentityUserRole<string>>().ToTable("UserRoles");
builder.Entity<IdentityUserClaim<string>>().ToTable("UserClaims");
builder.Entity<IdentityUserLogin<string>>().ToTable("UserLogins");
builder.Entity<IdentityRoleClaim<string>>().ToTable("RoleClaims");
builder.Entity<IdentityUserToken<string>>().ToTable("UserTokens");
}
public DbSet<BlogPost> BlogPosts { get; set; }
<!-- etc... -->
}
Как видно из этого фрагмента кода, я игнорирую некоторые свойства, так как эти свойства не нужны. Кроме этого, я просто сопоставляю каждую модель идентичности с соответствующей таблицей, поскольку использую собственные имена (я ненавижу AspNetRoles
, бла, бла, имена столов).
После этого я пошел дальше и изменил свой Startup.cs
класс, чтобы включить следующее:
public class Startup
{
public StartUp(IHostingEnvironment env)
{
var builder = new ConfigurationBuilder()
.SetBasePath(env.ContentRootPath)
.AddJsonFile("appsettings.json", optional: true, reloadOnChange: true)
.AddJsonFile($"appsettings.{env.EnvironmentName}.json", optional: true)
.AddEnvironmentVariables();
Configuration = builder.Build();
}
public IConfigurationRoot Configuration { get; }
public void ConfigureServices(IServiceCollection services)
{
services.AddDbContext<DatabaseContext>(options =>
options.UseMySQL(Configuration.GetConnectionString("DatabaseContext")));
services.AddIdentity<User, IdentityRole>()
AddEntityFrameworkStores<DatabaseContext>()
.AddDeafultRokenProviders();
services.AddMvc();
<!-- Bla, bla, bla -->
}
}
ПРОБЛЕМА
После внесения этих изменений я бы предположил, что все настроено правильно (дайте мне знать, если что-то не хватает). Отсюда я могу создать свою миграцию инициализации, выполнив следующую команду:
dotnet ef migrations add init
Я вижу, что Migrations
папка добавлена в мой проект.
Проблема 1: не должно ли это создать Configuration.cs
класс в моей папке миграций, где я могу заполнить базу данных?
Я также предположил бы, что смогу обновить базу данных с помощью следующей команды:
dotnet ef database update
Проблема 2: Но это дает мне следующую ошибку:
В экземпляре объекта не задана ссылка на объект.
Трассировка стека:
System.NullReferenceException: Object reference not set to an instance of an object.
at MySQL.Data.Entity.Migrations.MySQLHistoryRepository.get_ExistsSql()
at Microsoft.EntityFrameworkCore.Migrations.HistoryRepository.Exists()
at Microsoft.EntityFrameworkCore.Migrations.Internal.Migrator.Migrate(String targetMigration)
at Microsoft.EntityFrameworkCore.Design.MigrationsOperations.UpdateDatabase(String targetMigration, String contextType)
at Microsoft.EntityFrameworkCore.Tools.Cli.DatabaseUpdateCommand.<>c__DisplayClass0_0.<Configure>b__0()
at Microsoft.Extensions.CommandLineUtils.CommandLineApplication.Execute(String[] args)
at Microsoft.EntityFrameworkCore.Tools.Cli.Program.Main(String[] args)
ВОПРОС
Это первый раз, когда я использую EF Code-first с сервером MySQL в ASP.NET Core, что означает, что я в основном использую это без достаточных знаний.