问题
I am trying to build Membership system using ASP.NET Identity 2.1, ASP.NET Web API 2.2 and i need to extend IdentityUserRole
to add another PK to its table like that:
public class ApplicationUserRoles : IdentityUserRole
{
public Guid ProjectId { get; set; }
public Project Project { get; set; }
}
public class Project
{
public Project()
{
ProjectId = new Guid();
}
public string ProjectName { get; set; }
[Key]
public Guid ProjectId { get; set; }
}
And in the DBcontext class I added :
protected override void OnModelCreating(System.Data.Entity.DbModelBuilder modelBuilder)
{
base.OnModelCreating(modelBuilder); // This needs to go before the other rules!
modelBuilder.Entity<ApplicationUserRoles>().HasKey(m => new {m.ProjectId, m.UserId, m.RoleId}).ToTable("ApplicationUserRoles");
}
public DbSet<ApplicationUserRoles> ApplicationUserRoles { get; set; }
and this did not work at all , i do not what i did wrong , add migration keep generate :
CreateTable(
"dbo.ApplicationUserRoles",
c => new
{
UserId = c.String(nullable: false, maxLength: 128),
RoleId = c.String(nullable: false, maxLength: 128),
ProjectId = c.Guid(nullable: false),
})
.PrimaryKey(t => new { t.UserId, t.RoleId })
.ForeignKey("dbo.AspNetUserRoles", t => new { t.UserId, t.RoleId })
.ForeignKey("dbo.Projects", t => t.ProjectId, cascadeDelete: true)
.Index(t => new { t.UserId, t.RoleId })
.Index(t => t.ProjectId);
}
As you can see PrimaryKey(t => new { t.UserId, t.RoleId })
. I need it to be PrimaryKey(t => new { t.ProjectId,t.UserId, t.RoleId })
回答1:
I got it work finally and here what i did :
at the signature of IdentityUser myApplicationUser inherits from it
public class IdentityUser<TKey, TLogin, TRole, TClaim> : IUser<TKey>
where TLogin : Microsoft.AspNet.Identity.EntityFramework.IdentityUserLogin<TKey>
where TRole : Microsoft.AspNet.Identity.EntityFramework.IdentityUserRole<TKey>
where TClaim : Microsoft.AspNet.Identity.EntityFramework.IdentityUserClaim<TKey>
{
}
it accepts my custom definition of IdentityUserRole.
my class ApplicationUser i needed to implement the right type:
public class ApplicationUser : IdentityUser<string, IdentityUserLogin, ApplicationUserSecurityProfile, IdentityUserClaim>
{
}
and my role:
public class ApplicationSecurityProfile : IdentityRole<string, ApplicationUserSecurityProfile>
{
}
and my ApplicationDbContext:
public class ApplicationDbContext : IdentityDbContext<ApplicationUser, ApplicationSecurityProfile, string, IdentityUserLogin, ApplicationUserSecurityProfile, IdentityUserClaim>, IContext
{
}
and my UserStore:
public class ApplicationUserStore : UserStore<ApplicationUser, ApplicationSecurityProfile, string, IdentityUserLogin, ApplicationUserSecurityProfile, IdentityUserClaim>, IUserStore<ApplicationUser>
{
public ApplicationUserStore ApplicationDbContext context)
: base(context)
{
}
}
and myRoleStore :
public class ApplicationSecurityProfileStore : RoleStore<ApplicationSecurityProfile, string, ApplicationUserSecurityProfile>
{
public ApplicationSecurityProfileStore(ApplicationDbContext context)
: base(context)
{
}
}
then i used my custom classes in the my custom mangers :
RoleManger :
public class ApplicationSecurityProfileManager : RoleManager<ApplicationSecurityProfile>
{
private ApplicationDbContext db = new ApplicationDbContext();
public ApplicationSecurityProfileManager(IRoleStore<ApplicationSecurityProfile, string> roleStore)
: base(roleStore)
{
}
public static ApplicationSecurityProfileManager Create(IdentityFactoryOptions<ApplicationSecurityProfileManager> options, IOwinContext context)
{
var appRoleManager = new ApplicationSecurityProfileManager(new ApplicationSecurityProfileStore(context.Get<ApplicationDbContext>()));
return appRoleManager;
}
}
my UserManager
public class ApplicationUserManager : UserManager<ApplicationUser>
{
public ApplicationUserManager(ApplicationUserStore store)
: base(store)
{
}
public static ApplicationUserManager Create(IdentityFactoryOptions<ApplicationUserManager> options, IOwinContext context)
{
var appDbContext = context.Get<ApplicationDbContext>();
var appUserManager = new ApplicationUserManager(new ApplicationUserStore(appDbContext));
// Configure validation logic for usernames
appUserManager.UserValidator = new UserValidator<ApplicationUser>(appUserManager)
{
AllowOnlyAlphanumericUserNames = true,
RequireUniqueEmail = true
};
// Configure validation logic for passwords
appUserManager.PasswordValidator = new PasswordValidator
{
RequiredLength = 6,
RequireNonLetterOrDigit = true,
RequireDigit = false,
RequireLowercase = true,
RequireUppercase = true,
};
appUserManager.EmailService = new AspNetIdentity.WebApi.Services.EmailService();
var dataProtectionProvider = options.DataProtectionProvider;
if (dataProtectionProvider != null)
{
appUserManager.UserTokenProvider = new DataProtectorTokenProvider<ApplicationUser>(dataProtectionProvider.Create("ASP.NET Identity"))
{
//Code for email confirmation and reset password life time
TokenLifespan = TimeSpan.FromHours(6)
};
}
return appUserManager;
}
}
and it works finally
来源:https://stackoverflow.com/questions/34432357/cant-extend-identityuserrole-cs-to-add-new-composite-key-to-dbo-aspnetuserroles