asp.net-core - User 表不是使用 Entity Framework Core 3.1 在 MySql 数据库中创建的(代码优先方法)

标签 asp.net-core entity-framework-core ef-code-first mysql-workbench asp.net-core-3.1

如何使用 Code First 方法和 Entity Framework Core 3.1 在 MySql 数据库中创建用户表?

"DataAccessMySqlProvider": "server=localhost;database=jahan_alpha;uid=xxxx;password=xxxx" in appsettings.json

在startup.cs中:

public void ConfigureServices(IServiceCollection services)
{
   services.AddDbContext<ApplicationDbContext>(options =>
            options.UseMySQL(Configuration["ConnectionStrings:DataAccessMySqlProvider"],
            b => b.MigrationsAssembly("Alpha.DataAccess")));
   // .UseMySQL is in Microsoft.EntityFrameworkCore namespace
}

我在包管理器控制台中运行Add-Migration Init-MySql-database,然后运行Update-database。 这样做之后,我得到了这个错误:

PM> Update-Database Build started... Build succeeded.
Microsoft.EntityFrameworkCore.Infrastructure[10403]
      Entity Framework Core 3.1.3 initialized 'ApplicationDbContext' using provider 'Pomelo.EntityFrameworkCore.MySql' with options:
MigrationsAssembly=Alpha.DataAccess 
Microsoft.EntityFrameworkCore.Database.Command[20101]
      Executed DbCommand (1,299ms) [Parameters=[], CommandType='Text', CommandTimeout='30']
      CREATE DATABASE `jahan_alpha`; Microsoft.EntityFrameworkCore.Database.Command[20101]
      Executed DbCommand (9,281ms) [Parameters=[], CommandType='Text', CommandTimeout='30']
      CREATE TABLE `__EFMigrationsHistory` (
          `MigrationId` varchar(95) NOT NULL,
          `ProductVersion` varchar(32) NOT NULL,
          CONSTRAINT `PK___EFMigrationsHistory` PRIMARY KEY (`MigrationId`)
      ); Microsoft.EntityFrameworkCore.Database.Command[20101]
      Executed DbCommand (118ms) [Parameters=[], CommandType='Text', CommandTimeout='30']
      SELECT 1 FROM INFORMATION_SCHEMA.TABLES WHERE TABLE_SCHEMA='jahan_alpha' AND TABLE_NAME='__EFMigrationsHistory';
Microsoft.EntityFrameworkCore.Database.Command[20101]
      Executed DbCommand (5ms) [Parameters=[], CommandType='Text', CommandTimeout='30']
      SELECT `MigrationId`, `ProductVersion`
      FROM `__EFMigrationsHistory`
      ORDER BY `MigrationId`; Microsoft.EntityFrameworkCore.Migrations[20402]
      Applying migration '20200515231101_Init-MySql'. Applying migration '20200515231101_Init-MySql'. fail:
Microsoft.EntityFrameworkCore.Database.Command[20102]
      Failed executing DbCommand (181ms) [Parameters=[], CommandType='Text', CommandTimeout='30']
      ALTER TABLE `User` DROP INDEX `UserNameIndex`; Failed executing DbCommand (181ms) [Parameters=[], CommandType='Text',
CommandTimeout='30'] ALTER TABLE `User` DROP INDEX `UserNameIndex`;
MySql.Data.MySqlClient.MySqlException (0x80004005): Table
'jahan_alpha.user' doesn't exist  --->
MySql.Data.MySqlClient.MySqlException (0x80004005): Table
'jahan_alpha.user' doesn't exist
    at MySqlConnector.Core.ResultSet.ReadResultSetHeaderAsync(IOBehavior ioBehavior) in C:\projects\mysqlconnector\src\MySqlConnector\Core\ResultSet.cs:line 49
    at MySql.Data.MySqlClient.MySqlDataReader.ActivateResultSet() in C:\projects\mysqlconnector\src\MySqlConnector\MySql.Data.MySqlClient\MySqlDataReader.cs:line 130
    at MySql.Data.MySqlClient.MySqlDataReader.CreateAsync(CommandListPosition commandListPosition, ICommandPayloadCreator payloadCreator, IDictionary`2 cachedProcedures, IMySqlCommand command, CommandBehavior behavior, IOBehavior ioBehavior, CancellationToken cancellationToken) in C:\projects\mysqlconnector\src\MySqlConnector\MySql.Data.MySqlClient\MySqlDataReader.cs:line 391
    at MySqlConnector.Core.CommandExecutor.ExecuteReaderAsync(IReadOnlyList`1 commands, ICommandPayloadCreator payloadCreator, CommandBehavior behavior, IOBehavior ioBehavior, CancellationToken cancellationToken) in C:\projects\mysqlconnector\src\MySqlConnector\Core\CommandExecutor.cs:line 62
    at MySql.Data.MySqlClient.MySqlCommand.ExecuteNonQueryAsync(IOBehavior ioBehavior, CancellationToken cancellationToken) in C:\projects\mysqlconnector\src\MySqlConnector\MySql.Data.MySqlClient\MySqlCommand.cs:line 226
    at MySql.Data.MySqlClient.MySqlCommand.ExecuteNonQuery() in C:\projects\mysqlconnector\src\MySqlConnector\MySql.Data.MySqlClient\MySqlCommand.cs:line 74
    at Microsoft.EntityFrameworkCore.Storage.RelationalCommand.ExecuteNonQuery(RelationalCommandParameterObject parameterObject)
    at Microsoft.EntityFrameworkCore.Migrations.MigrationCommand.ExecuteNonQuery(IRelationalConnection connection, IReadOnlyDictionary`2 parameterValues)
    at Microsoft.EntityFrameworkCore.Migrations.Internal.MigrationCommandExecutor.ExecuteNonQuery(IEnumerable`1 migrationCommands, IRelationalConnection connection)
    at Microsoft.EntityFrameworkCore.Migrations.Internal.Migrator.Migrate(String targetMigration)
    at Pomelo.EntityFrameworkCore.MySql.Migrations.Internal.MySqlMigrator.Migrate(String targetMigration)
    at Microsoft.EntityFrameworkCore.Design.Internal.MigrationsOperations.UpdateDatabase(String targetMigration, String contextType)
    at Microsoft.EntityFrameworkCore.Design.OperationExecutor.UpdateDatabaseImpl(String targetMigration, String contextType)
    at Microsoft.EntityFrameworkCore.Design.OperationExecutor.UpdateDatabase.<>c__DisplayClass0_0.<.ctor>b__0()
    at Microsoft.EntityFrameworkCore.Design.OperationExecutor.OperationBase.Execute(Action action)
Table 'jahan_alpha.user' doesn't exist

jahan_alpha.user' doesn't exist

ApplicationDbContext:

namespace Alpha.DataAccess
{
    public class ApplicationDbContext : IdentityDbContext<User, Role, int, UserClaim, UserRole, UserLogin, RoleClaim, UserToken>
    {
        public ApplicationDbContext(DbContextOptions<ApplicationDbContext> options) : base(options)
        {

        }
        // some codes...

        protected override void OnModelCreating(ModelBuilder modelBuilder)
        {
            // it should be placed here, otherwise it will rewrite the following settings!
            base.OnModelCreating(modelBuilder);

            modelBuilder.Entity<RoleClaim>(builder =>
            {
                builder.HasOne(roleClaim => roleClaim.Role).WithMany(role => role.Claims).HasForeignKey(roleClaim => roleClaim.RoleId);
                builder.ToTable("RoleClaim");
            });
            modelBuilder.Entity<Role>(builder =>
            {
                builder.ToTable("Role");
            });
            modelBuilder.Entity<UserClaim>(builder =>
            {
                builder.HasOne(userClaim => userClaim.User).WithMany(user => user.Claims).HasForeignKey(userClaim => userClaim.UserId);
                builder.ToTable("UserClaim");
            });
            modelBuilder.Entity<UserLogin>(builder =>
            {
                builder.HasOne(userLogin => userLogin.User).WithMany(user => user.Logins).HasForeignKey(userLogin => userLogin.UserId);
                builder.ToTable("UserLogin");
            });

            modelBuilder.Entity<User>(builder =>
            {
                builder.ToTable("User"); //.HasMany(e => e.Comments).WithOne().OnDelete(DeleteBehavior.Cascade);
            });
            modelBuilder.Entity<UserRole>(builder =>
            {
                builder.HasOne(userRole => userRole.Role).WithMany(role => role.Users).HasForeignKey(userRole => userRole.RoleId);
                builder.HasOne(userRole => userRole.User).WithMany(user => user.Roles).HasForeignKey(userRole => userRole.UserId);
                builder.ToTable("UserRole");
            });
            modelBuilder.Entity<UserToken>(builder =>
            {
                builder.HasOne(userToken => userToken.User).WithMany(user => user.UserTokens).HasForeignKey(userToken => userToken.UserId);
                builder.ToTable("UserToken");
            });

            // some codes...
        }

        public static async Task CreateAdminAccount(IServiceProvider serviceProvider, IConfiguration configuration)
        {
            UserManager<User> userManager = serviceProvider.GetRequiredService<UserManager<User>>();
            RoleManager<Role> roleManager = serviceProvider.GetRequiredService<RoleManager<Role>>();

            string userName = configuration["Data:AdminUser:Name"];
            string email = configuration["Data:AdminUser:Email"];
            string password = configuration["Data:AdminUser:Password"];
            string role = configuration["Data:AdminUser:Role"];

            if (await userManager.FindByNameAsync(userName) == null)
            {
                if (await roleManager.FindByNameAsync(role) == null)
                {
                    await roleManager.CreateAsync(new Role(role));
                }

                User user = new User
                {
                    Email = email,
                    UserName = userName
                };
                var result = userManager.CreateAsync(user, password);
                if (result.IsCompletedSuccessfully)
                {
                    await userManager.AddToRoleAsync(user, role);
                }
            }
        }
    }
}

最佳答案

基于执行的第一个命令是 ALTER DATABASE ,我假设 1) 您已经有一个手动生成的数据库,其中包含表 User当您生成初始迁移时 2) 然后您删除了数据库 3) 然后您运行 Update-Database命令。

将迁移视为将数据库从一种稳定状态移动到另一种稳定状态的增量补丁。如果您想查看更新数据库时将运行的实际 SQL,您可以发出 dotnet ef migrations script -i -o migrations.sql命令。这将生成一个完整的脚本,其中包含从初始状态到当前状态的所有迁移。

我进一步假设您实际上有一个 DbSet<User>您的属性(property) ApplicationDbContext隐藏在某处// some codes...代码块

正如评论中已经指出的,您需要做的是;

  • 删除 jahan_alpha来自服务器的数据库localhost
  • 删除 Migrations完全来自您的项目的文件夹
  • 运行dotnet ef migrations add initial
  • 运行dotnet ef migrations script -i -o migrations.sql
  • 验证migrations.sql中的SQL命令文件正确(例如 CREATE DATABASE 在任何 ALTER DATABASE 实例之前)
  • 现在运行 dotnet ef database update - 这将生成jahan_alpha具有代码优先项目中定义架构的数据库

关于asp.net-core - User 表不是使用 Entity Framework Core 3.1 在 MySql 数据库中创建的(代码优先方法),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/61765388/

相关文章:

c# - 使用托管标识运行 EF Core 迁移的 Azure DevOps 管道

asp.net-core - ASP.NET core后台服务通过signalR发送数据

asp.net-core - 缺少刷新 token 和角色 (OpenIddict)

asp.net-core - 在 Entity Framework 中使用两个不同的连接字符串进行迁移

performance - Entity Framework 查询很慢,但 SqlQuery 中的相同 SQL 很快

c# - 找出实体是否附加到 dbContext 的最合理方法是什么?

c# - 键列具有不同名称时的实体拆分?

c# - 如何将 ViewDataDictionary 或 ModelStateDictionary 注入(inject) TagHelper?

c# - 为什么 EF7/Core 插入重复记录?

c# - DbContextBuilder 不包含 UseSqlite 的定义