如果要自定义模型,会遇到创建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);
}