代码之家  ›  专栏  ›  技术社区  ›  x19

代码优先的方法不会使用Entity Framework Core 3.1在MySql中创建表

  •  0
  • x19  · 技术社区  · 5 年前

    如何使用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

    应用程序:

    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);
                    }
                }
            }
        }
    }
    
    0 回复  |  直到 5 年前
        1
  •  1
  •   joakimriedel    5 年前

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

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

    我进一步假设你实际上有一个 DbSet<User> 您的财产 ApplicationDbContext 隐藏的某个地方 // some codes... 代码块

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

    • 放下 jahan_alpha 来自服务器的数据库 localhost
    • 删除 Migrations 文件夹完全来自您的项目
    • 运行 dotnet ef migrations add initial
    • 运行 netsef迁移脚本-i-omigrations.sql
    • 验证中的SQL命令 migrations.sql 文件是正确的(例如 CREATE DATABASE 在任何实例之前 更改数据库 )
    • 现在运行 dotnet ef database update -这将生成 日本 具有在代码优先项目中定义的模式的数据库