net core2.2 使用Identity数据库结构,在mysql创建数据库的问题

如果要自定义模型,会遇到创建mysql数据库时字段类型错误,还有无法初始化角色和用户数据等问题

1 如何自定义模型, 目前只定义三个模型,IdentityUser,IdentityRole,IdentityUserRole


public class ApplicationUser : IdentityUser // IdentityUser 必须引用 Microsoft.AspNetCore.Identity;

    {

        public ApplicationUser() : base()

        {

            Claims = new List<IdentityUserClaim<string>>();

            Logins = new List<IdentityUserLogin<string>>();

            Tokens = new List<IdentityUserToken<string>>();

        }

        // 在 IdentityUser 的基础上拓展两个字段属性。

        public int Gender { get; set; }

        // 以下四个属性是 Identity 内置的四个权限属性,照着添加上去再权限校验的时候用到。

        public ICollection<IdentityUserClaim<string>> Claims { get; set; }

        public ICollection<IdentityUserLogin<string>> Logins { get; set; }

        public ICollection<IdentityUserToken<string>> Tokens { get; set; }     

        public virtual ICollection<ApplicationUserRole> UserRoles { get; } = new List<ApplicationUserRole>();

    }



public class ApplicationRole : IdentityRole

    {

        public ApplicationRole() : base()

        {

        }

        public ApplicationRole(string roleName) : base(roleName)

        {

            Name = roleName;

        }

        public virtual ICollection<ApplicationUserRole> UserRoles { get; } = new List<ApplicationUserRole>();

    }


public class ApplicationUserRole : IdentityUserRole<string>

    {

        public ApplicationUserRole() : base()

        {

        }

        public virtual ApplicationUser User { get; set; }

        public virtual ApplicationRole Role { get; set; }

    }


2 创建数据库结构

public class ApplicationDbContext : IdentityDbContext

        <

    ApplicationUser, // TUser

    ApplicationRole, // TRole

    string, // TKey

    IdentityUserClaim<string>, // TUserClaim

    ApplicationUserRole, // TUserRole,

    IdentityUserLogin<string>, // TUserLogin

    IdentityRoleClaim<string>, // TRoleClaim

    IdentityUserToken<string> // TUserToken

>  ///必须要这样写,把所有都加上

    {

        public ApplicationDbContext(DbContextOptions<ApplicationDbContext> options)

            : base(options)

        {

        }

        public DbSet<ApplicationUserRole> ApplicationUserRole { get; set; }   //自定义的用户角色

        public DbSet<ApplicationUser> ApplicationUser { get; set; }   //自定义的用户

        public DbSet<ApplicationRole> ApplicationRole { get; set; }   //自定义的角色

        public DbSet<Anime> Anime { get; set; }

        protected override void OnModelCreating(ModelBuilder builder)

        {

            base.OnModelCreating(builder);

            // Customize the ASP.NET Identity model and override the defaults if needed.

            // For example, you can rename the ASP.NET Identity table names and more.

            // Add your customizations after calling base.OnModelCreating(builder);

            //这是为了在mysql数据库的字段类型转换

             foreach (var entityType in builder.Model.GetEntityTypes())

            {

                foreach (var property in entityType.GetProperties())

                {

                    if (property.ClrType == typeof(bool))

                    {

                        property.SetValueConverter(new BoolToIntConverter());

                    }

                }

            }

            builder.Entity<ApplicationUser>().ToTable("AspNetUsers");

            builder.Entity<ApplicationUserRole>().ToTable("AspNetUserRoles");

            builder.Entity<ApplicationRole>().ToTable("AspNetRoles");

            // 在自定义 ApplicationUser 类中已经添加了如下字段属性,在这里做关联配置

            builder.Entity<ApplicationUser>(b =>

            {

                // Each User can have many UserClaims

                b.HasMany(e => e.Claims)

                    .WithOne()

                    .HasForeignKey(uc => uc.UserId)

                    .IsRequired();

                // Each User can have many UserLogins

                b.HasMany(e => e.Logins)

                    .WithOne()

                    .HasForeignKey(ul => ul.UserId)

                    .IsRequired();

                // Each User can have many UserTokens

                b.HasMany(e => e.Tokens)

                    .WithOne()

                    .HasForeignKey(ut => ut.UserId)

                    .IsRequired();

                // Each User can have many entries in the UserRole join table

                b.HasMany(e => e.UserRoles)

                    .WithOne()

                    .HasForeignKey(ur => ur.UserId)

                    .IsRequired();

            });


            builder.Entity<ApplicationUserRole>()

                        .HasOne(p => p.User)

                        .WithMany(b => b.UserRoles)

                        .HasForeignKey(p => p.UserId);

            builder.Entity<ApplicationUserRole>()

                .HasOne(x => x.Role)

                .WithMany(x => x.UserRoles)

                .HasForeignKey(p => p.RoleId);

        }

    }

    public class BoolToIntConverter : ValueConverter<bool, int>

    {

        public BoolToIntConverter(ConverterMappingHints mappingHints = null)

            : base(

                  v => Convert.ToInt32(v),

                  v => Convert.ToBoolean(v),

                  mappingHints)

        {

        }

        public static ValueConverterInfo DefaultInfo { get; }

            = new ValueConverterInfo(typeof(bool), typeof(int), i => new BoolToIntConverter(i.MappingHints));

    }


3 注册中间件Startup.cs

public void ConfigureServices(IServiceCollection services)

        {

services.AddIdentity<ApplicationUser, ApplicationRole>()

                .AddEntityFrameworkStores<ApplicationDbContext>()

                .AddDefaultTokenProviders();

        }


4 初始化数据库表内容  DbInitializer.cs

public class DbInitializer

    {

        public static async Task Initialize(ApplicationDbContext context, UserManager<ApplicationUser> userManager,RoleManager<ApplicationRole> roleManager)

        {

            bool b = context.Database.EnsureCreated(); 

            if (context.Users.Count() > 0)

            {

                return;  // DB has been seeded 

            }

            await CreateDefaultUserAndRole(userManager, roleManager);

        }

        private static async Task CreateDefaultUserAndRole(UserManager<ApplicationUser> userManager, RoleManager<ApplicationRole> roleManager)

        {

            string roleAdmin = "admin";

            string roleUser = "user";

            await CreateDefaultRole(roleManager, roleAdmin);

            await CreateDefaultRole(roleManager, roleUser);

            var user = await CreateDefaultUser(userManager);

            await AddDefaultRoleToDefaultUser(userManager, roleAdmin, user);

            await AddDefaultRoleToDefaultUser(userManager, roleUser, user);

        }

        private static async Task CreateDefaultRole(RoleManager<ApplicationRole> roleManager, string roleName)

        {

            var role = new ApplicationRole {  Name = roleName, NormalizedName = roleName };

            await roleManager.CreateAsync(role);

            //await roleManager.CreateAsync(new ApplicationRole(roleName));

        }

        private static async Task<ApplicationUser> CreateDefaultUser(UserManager<ApplicationUser> userManager)

        {

            var user = new ApplicationUser { Email = "5140075@qq.com", UserName = "admin" };

            await userManager.CreateAsync(user,"abc123");

            var createdUser = await userManager.FindByEmailAsync("5140075@qq.com");

            return createdUser;

        }

        private static async Task AddDefaultRoleToDefaultUser(UserManager<ApplicationUser> userManager, string role, ApplicationUser user)

        {

            await userManager.AddToRoleAsync(user, role);

        }

    }


5 执行初始化  Program.cs

public class Program

    {

        public static void Main(string[] args)

        {

            //BuildWebHost(args).Run();

            var host = BuildWebHost(args);

            using (var scope = host.Services.CreateScope())

            {

                var services = scope.ServiceProvider;

                try

                {

                    var context = services.GetRequiredService<ApplicationDbContext>();

                    var userManager = services.GetRequiredService<UserManager<ApplicationUser>>();

                    var roleManager = services.GetRequiredService<RoleManager<ApplicationRole>>();

                    DbInitializer.Initialize(context, userManager, roleManager).Wait();

                }

                catch (Exception ex)

                {

                    var logger = services.GetRequiredService<ILogger<Program>>();

                    logger.LogError(ex, "An error occurred while seeding the database.");

                }

            }

            host.Run();

        }

        public static IWebHost BuildWebHost(string[] args) =>

            WebHost.CreateDefaultBuilder(args)

                .UseStartup<Startup>()

                .Build();

    }


6 如果不想用程序包管理控制台去初始化数据库结构,可以在Startup.cs增加代码

public void InitDataBase(IApplicationBuilder app)

        {

            using (var serviceScope = app.ApplicationServices.GetService<IServiceScopeFactory>().CreateScope())

            {

                serviceScope.ServiceProvider.GetRequiredService<ApplicationDbContext>().Database.Migrate();

                var context = serviceScope.ServiceProvider.GetRequiredService<ApplicationDbContext>();

                bool b = context.Database.EnsureCreated();//有就不创建

                //context.Database.Migrate();

            }

        }

public void Configure(IApplicationBuilder app, IHostingEnvironment env)

        {

        InitDataBase(app);

        }

©著作权归作者所有,转载或内容合作请联系作者
【社区内容提示】社区部分内容疑似由AI辅助生成,浏览时请结合常识与多方信息审慎甄别。
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。
禁止转载,如需转载请通过简信或评论联系作者。

友情链接更多精彩内容