我一直在开发一个网站很长一段时间。最近我意识到我需要和身份模型(使用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... -->
}
从这个代码堆中可以看出,我忽略了一些属性,因为不需要这些属性。除此之外,我只是将每个Identity模型映射到相应的表中,因为我使用自定义名称(我讨厌AspNetRoles
,bla,bla,表名)。
在此之后,我继续改变我的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 -->
}
}
问题
进行这些更改后,我会假设所有内容都已正确设置(让我知道是否有任何遗漏)。从这里我可以通过运行以下命令来创建我的init迁移:
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)
问题
这是我第一次在ASP.NET Core中使用EF Code-first和MySQL服务器,这意味着我基本上没有足够的知识使用它。