简体   繁体   中英

Custom Identity EntityFrameworkCore

I'm trying customize EntityFrameworkCore Identity with AspNetUsers, AspNetRoles and AspNetUserRoles only... Is it possible?

My code:

ApplicationUser.cs

public class ApplicationUser : IdentityUser<int>
{
}

ApplicationDbContext.cs

public class ApplicationDbContext : IdentityDbContext<ApplicationUser, IdentityRole<int>, int>
{
    public ApplicationDbContext(DbContextOptions<ApplicationDbContext> options)
        : base(options)
    {
    }

    protected override void OnModelCreating(ModelBuilder builder)
    {
        //base.OnModelCreating(builder);

        builder.Entity<IdentityUser<int>>().ForSqlServerToTable("AspNetUsers")
            //.Ignore(x => x.Claims)
            //.Ignore(x => x.Logins)
            .HasKey(x => x.Id);

        builder.Entity<IdentityRole<int>>().ForSqlServerToTable("AspNetRoles")
            //.Ignore(x => x.Claims)
           .HasKey(x => x.Id);

        builder.Entity<IdentityUserRole<int>>().ForSqlServerToTable("AspNetUserRoles")
            .HasKey(x => new { x.UserId, x.RoleId });

        builder.Ignore<IdentityUserLogin<int>>();
        builder.Ignore<IdentityUserToken<int>>();
        builder.Ignore<IdentityUserClaim<int>>();
        builder.Ignore<IdentityRoleClaim<int>>();
    }
}

Startup.cs

public void ConfigureServices(IServiceCollection services)
        {
          ...
            services.AddIdentity<ApplicationUser, IdentityRole<int>>()
                .AddEntityFrameworkStores<ApplicationDbContext, int>()
                .AddDefaultTokenProviders();

            ...
        }

AccountController.cs

public async Task<IActionResult> Register(RegisterViewModel model, string returnUrl = null)
    {
        ...
            var user = new ApplicationUser { UserName = model.Email, Email = model.Email };
            var result = await _userManager.CreateAsync(user, model.Password);
            if (result.Succeeded)
            {
                await _signInManager.SignInAsync(user, isPersistent: false);
                return RedirectToLocal(returnUrl);
            }
            AddErrors(result);
        }
        return View(model);
    }

CreateAsync = success, but SignInAsync return InvalidOperationException: Cannot create a DbSet for 'IdentityUserClaim`1' because this type is not included in the model for the context.

My database contains only tables AspNetRoles, AspNetUsers and AspNetUserRoles with default columns(Id's type int).

Thanks.

I had a similar issue, but I had created an inherited XXXRole. The error was: Cannot create a DbSet for 'XXXRole' because this type is not included in the model for the context.

It turns out I needed to also let the AppDbContext know which role was being used, otherwise it assumes...

So I added it to the generic type for IdentityDbContext:

public class ApplicationDbContext : IdentityDbContext<XXXUser, XXXRole, string>
{
....
}

In this case above, I suggest you make a new concrete class inheriting from "IdentityRole". Then you would do something like:

public class ApplicationDbContext : IdentityDbContext<XXXUser, XXXRole, int>
{
....
}

I believe the same data type of key is used for both Users and Roles - so you may also need to create XXXUser : IdentityUser

I stumbled upon the same problem, and even thou my mistake was stupid it could help someone in the future:

I had named

public class IdentityDbContext: IdentityDbContext<User> { .... }

And when I referenced it I did not specify from what namespace it should take IdentityDbContext (*the correct was MyNamespace.IdentityDbContext (doh!) )

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM