mrahhal / MR.AspNet.Identity.EntityFramework6

EntityFramework 6 provider + InMemory providers for Asp.Net Core Identity.
MIT License
41 stars 21 forks source link

Change Key type to int #5

Closed mo-esmp closed 7 years ago

mo-esmp commented 7 years ago

I tried to change Key type to int. here is my custom classes

public class ApplicationUser : IdentityUser<int, CustomUserLogin, CustomUserRole, CustomUserClaim>
{
}

public class CustomUserRole : IdentityUserRole<int> { }

public class CustomUserClaim : IdentityUserClaim<int> { }

public class CustomRoleClaim : IdentityRoleClaim<int> { }

public class CustomUserLogin : IdentityUserLogin<int> { }

public class CustomRole : IdentityRole<int, CustomUserRole, CustomRoleClaim>
{
    public CustomRole()
    {
    }

    public CustomRole(string name)
    {
        Name = name;
    }
}

public class CustomUserStore : UserStore<ApplicationUser, ApplicationRole, CustomUserRole, CustomUserClaim, CustomUserLogin, CustomRoleClaim, ApplicationDbContext, int>
{
    public CustomUserStore(ApplicationDbContext context)
        : base(context)
    {
    }
}

public class CustomRoleStore : RoleStore<ApplicationRole, CustomUserRole, CustomRoleClaim, ApplicationDbContext, int>
{
    public CustomRoleStore(ApplicationDbContext context)
        : base(context)
    {
    }
}

and in startup class:

services.AddScoped(_ => new ApplicationDbContext("Server=.;Database=AspCoreEf6;Trusted_Connection=True;MultipleActiveResultSets=true"));
services.AddIdentity<ApplicationUser, ApplicationRole>().AddEntityFrameworkStores<ApplicationDbContext>();

when I run project i get this error:

GenericArguments[0], 'AspCoreEf6.Models.ApplicationUser', on 'MR.AspNet.Identity.EntityFramework6.UserStore`3[TUser,TRole,TContext]' violates the constraint of type 'TUser'.

I don't know how to change UserStore and RoleStore and use CustomUserStore and CustomRoleStore.

mrahhal commented 7 years ago

You defined a CustomUserRole so you must extend CustomRoleStore from:

RoleStore<CustomRole, CustomUserRole, CustomRoleClaim, ApplicationDbContext, int>

Note that you're writing ApplicationRole when you should be using your custom CustomRole. The same applies to your custom CustomUserStore.

Also for

services.AddIdentity<ApplicationUser, ApplicationRole>().AddEntityFrameworkStores<ApplicationDbContext>();

It should be CustomRole.

And your ApplicationDbContext should extend:

IdentityDbContext<ApplicationUser, CustomRole, string, CustomUserLogin, CustomUserRole, CustomUserClaim, CustomRoleClaim>

Something like that. In short, make sure you're using your custom identity classes as generic arguments everywhere. If you miss one spot, you'll get that kind of error.

Try it out let me know.

joeizang commented 7 years ago

I am just doing something simpler than what he is doing, I am just changing the key from string to int. I simply added an ApplicationRole class which inherits IdentityRole and all I get are red squiggly lines in my context, ApplicationUser and the like.

`public class ApplicationUser : IdentityUser<int,ApplicationUser,ApplicationRole,IdentityUserClaim>
 {
     public int StateId { get; set; }
     public State StateOfOrigin { get; set; }
     public int AddressId { get; set; }
     public Address Address { get; set; }
}`

`public class ApplicationRole : IdentityRole<int, IdentityUserRole, IdentityRoleClaim>
 {
 }
 public class SchoolDb : IdentityDbContext<ApplicationUser, ApplicationRole, int, IdentityUserLogin,                  IdentityUserRole, IdentityUserClaim, IdentityRoleClaim>
 {
 }`
mrahhal commented 7 years ago

@joeizang you should note that the various Identity model classes are tightly coupled according to the key. You can see for example that IdentityUserClaim expects the key to be of type string. So in order to change the key you'll have to create your custom identity model classes.

You know, now that I think about it, choosing the key as int is pretty common and it's not a straightforward process if you're not accustomed to the Identity way of compositing classes. So maybe I should create a package that does that in this repository. It'll also serve as a good example of how to change the key.

mrahhal commented 7 years ago

@mo-esmp @joeizang while giving this a try I just realized how hard and tedious it is to actually do this so I'm going to make a package for an int key implementation with a sample. Almost done actually.

mo-esmp commented 7 years ago

@joeizang are you sure this code compiles public class ApplicationRole : IdentityRole<int, IdentityUserRole, IdentityRoleClaim> ?

Here is source code of `IdentityRole`
namespace MR.AspNet.Identity.EntityFramework6
{
  public class IdentityRole<TKey, TUserRole, TRoleClaim> 
    where TKey : IEquatable<TKey> 
    where TUserRole : IdentityUserRole<TKey> 
    where TRoleClaim : IdentityRoleClaim<TKey>
.
.
.
mrahhal commented 7 years ago

@mo-esmp it does not.

I'm finished, cleaning things up.

mrahhal commented 7 years ago

@mo-esmp @joeizang checkout the new 2.2.0 to use the implementation, it's in the MR.AspNet.Identity.EntityFramework6.Key.Int project. You can directly reference this as a nuget package. Refer to the sample Key.Int to see how it's used.

Also, you can look at MR.AspNet.Identity.EntityFramework6.Key.Int from now on and take it as an example of how to create your own implementation with your custom key type of choice if you need (maybe long?).

I'm closing this but do let me know if you face trouble getting this to work.

joeizang commented 7 years ago

I will give this a try and I will let you know how everything goes. I must say thank you for taking up our cause on this. You have have a good day now