C# EF使用新的ASP标识2映射不正确的表

C# EF使用新的ASP标识2映射不正确的表,c#,asp.net,entity-framework,asp.net-identity,C#,Asp.net,Entity Framework,Asp.net Identity,我正在尝试映射用户和组之间的一对多关系。我希望用户对他们加入的每个组都有一个单独的排名,只相对于该组。不幸的是,EF不会映射我想要的东西,我已经花了两天时间试图找出原因 IdentityModels.cs: namespace MapGroupsToRoles.Models { // You can add profile data for the user by adding more properties to your ApplicationUser class, please v

我正在尝试映射用户和组之间的一对多关系。我希望用户对他们加入的每个组都有一个单独的排名,只相对于该组。不幸的是,EF不会映射我想要的东西,我已经花了两天时间试图找出原因

IdentityModels.cs:

namespace MapGroupsToRoles.Models
{
    // You can add profile data for the user by adding more properties to your ApplicationUser class, please visit http://go.microsoft.com/fwlink/?LinkID=317594 to learn more.
    public class ApplicationUser : IdentityUser
    {
        public ApplicationUser() { this.RolesToGroups = new HashSet<GroupToRoles>(); }
        public virtual ICollection<GroupToRoles> RolesToGroups { get; set; }
        public async Task<ClaimsIdentity> GenerateUserIdentityAsync(UserManager<ApplicationUser> manager)
        {
            // Note the authenticationType must match the one defined in CookieAuthenticationOptions.AuthenticationType
            var userIdentity = await manager.CreateIdentityAsync(this, DefaultAuthenticationTypes.ApplicationCookie);
            // Add custom user claims here
            return userIdentity;
        }
    }
    public class GroupToRoles
    {
        public virtual int GroupToRolesId { get; set; }
        public GroupToRoles() { }
        public virtual ApplicationUser User { get; set; }
        public virtual Group Group { get; set; }
        public virtual ClanRole Role { get; set; }
    }
    public class ApplicationDbContext : IdentityDbContext<ApplicationUser>
    {
        public ApplicationDbContext()
            : base("DefaultConnection", throwIfV1Schema: false)
        {

        }

        public System.Data.Entity.DbSet<GroupToRoles> GroupToRolesTable { get; set; }
        public static ApplicationDbContext Create()
        {
            return new ApplicationDbContext();
        }
        protected override void OnModelCreating(DbModelBuilder modelbuilder)
        {
            modelbuilder.Entity<ApplicationUser>().ToTable("Users");
        //    modelbuilder.Entity<ApplicationUser>().Ignore(u => u.Id);
            modelbuilder.Entity<ApplicationUser>().HasKey(u => u.Id);           
            modelbuilder.Entity<ApplicationUser>().HasMany(u => u.RolesToGroups).WithRequired().WillCascadeOnDelete(true);

            modelbuilder.Entity<GroupToRoles>().ToTable("GroupToRolesTable").HasKey(u => u.GroupToRolesId);
            modelbuilder.Entity<IdentityUserLogin>().HasKey(u => u.ProviderKey);
            modelbuilder.Entity<IdentityUserRole>().HasKey(u => u.RoleId);

            modelbuilder.Entity<Group>().ToTable("Groups");
            modelbuilder.Entity<Group>().HasKey(u => u.GroupId);
            modelbuilder.Entity<Group>().HasMany(u => u.Roles).WithRequired().WillCascadeOnDelete(true);

        }
    }

}

公共虚拟ICollection角色组{get;set;}
在ApplicationUser类内部

C组:

namespace MapGroupsToRoles.Models
{
    public class Group
    {
        public int GroupId { get; set; }
        public Group() { this.Roles = new HashSet<GroupToRoles>(); }
        public virtual string GroupName { get; set; }
        public virtual ICollection<GroupToRoles> Roles { get; set; }
    }
}
名称空间MapGroupsToRoles.Models
{
公共课组
{
public int GroupId{get;set;}
公共组(){this.Roles=new HashSet();}
公共虚拟字符串GroupName{get;set;}
公共虚拟ICollection角色{get;set;}
}
}
对,那么我得到了什么结果? 1.两个哈希集(即Group.cs和ApplicationUser中的GroupToRoles集)均不显示。。。 2.组表显示组\组ID 1和组\组ID…1来自哪里

任何帮助都将不胜感激

编辑_____________

因此,我想重新迭代,将用户映射到组,其中每个组有一个角色,并且是多个组的成员。因此,它是用户和“GroupToRoles”类之间的一对多映射(该类反过来映射一对多组)

例如: 约翰是a、b、c组的成员 对于a组,他是管理员, b组他是一名成员 c组他是一名访客

我认为我不能使用(如果我错了请纠正我)标准ASP角色(这就是我创建“ClanRole”类的原因,因为我还希望每个用户都有一个全局角色,它将处理整个站点的管理权限(而不仅仅是用户创建的组)

基本上,我希望能够将ApplicationUser类映射到许多“GroupToRole”。从那里,其他一切都应该到位。然而,这是一个阻力,我不知道为什么


非常感谢

回答此问题所需的步骤远远超出预期。将在未来几周内编写一份指南,并在此处提供一个链接

简要概述:

  • 创建单独的上下文:添加到web.config并添加以下内容:

      public class MyContext : DbContext
      {
            public MyContext () : base("DefaultConnection")
            {
            }
            public static MyContext Create()
            {
                return new MyContext ();
            }
      }
    
  • 删除ApplicationDbContext,构建以快速找到引用它的位置,并用新上下文替换它们

  • 将fluent更改为(放入上下文中):

    public System.Data.Entity.DbSet GroupToRolesTable{get;set;}
    public System.Data.Entity.DbSet组{get;set;}
    public System.Data.Entity.DbSet用户{get;set;}
    模型创建时受保护的覆盖无效(DbModelBuilder modelbuilder)
    {
    modelbuilder.Entity().ToTable(“用户”);
    modelbuilder.Entity().HasKey(u=>u.Id);
    modelbuilder.Entity().HasMany(u=>u.RolesToGroups);//.WithRequired(/*u=>u.User*/).HasForeignKey(u=>u.UserId);
    modelbuilder.Entity().ToTable(“GroupToRolesTable”).HasKey(u=>u.GroupToRolesId);
    modelbuilder.Entity().HasKey(u=>u.ProviderKey);
    modelbuilder.Entity().HasKey(u=>u.RoleId);
    modelbuilder.Entity().ToTable(“组”);
    modelbuilder.Entity().HasKey(u=>u.GroupId);
    modelbuilder.Entity().HasMany(u=>u.Roles);///.WithRequired(/*u=>u.Group*/).HasForeignKey(u=>u.GroupId);
    }
    

  • 我真的把你的想法搞糊涂了

    为什么一个用户可以分配多个组?(与角色没有区别)。这个概念会产生大量冗余数据

    我认为一个用户只能分配一个组,0-1分配给多个组

    例如:应用程序有3个组:管理员、用户、匿名

    • 管理员拥有所有角色
    • 用户具有“主页、用户管理器等”角色
    • 匿名者扮演“家”的角色
    您必须更改实体的结构,如下所示:

    识别码

    public class IdentityUser<TKey, TLogin, TClaim, TGroup, TGroupRole> : IUser<TKey>
        where TLogin : IdentityUserLogin<TKey>
        where TClaim : IdentityUserClaim<TKey>
        where TGroup : IdentityGroup<TKey, TGroupRole>
        where TGroupRole : IdentityGroupRole<TKey>
    {
        public virtual string Email { get; set; }
        public virtual bool EmailConfirmed { get; set; }
        public virtual string PasswordHash { get; set; }
        public virtual string SecurityStamp { get; set; }
        public virtual string PhoneNumber { get; set; }
        public virtual bool PhoneNumberConfirmed { get; set; }
        public virtual bool TwoFactorEnabled { get; set; }
        public virtual DateTime? LockoutEndDateUtc { get; set; }
        public virtual bool LockoutEnabled { get; set; }
        public virtual int AccessFailedCount { get; set; }
        public virtual ICollection<TClaim> Claims { get; private set; }
        public virtual ICollection<TLogin> Logins { get; private set; }
        public virtual TGroup Group { get; set; }
        public virtual TKey Id { get; set; }
        public virtual string UserName { get; set; }
        public IdentityUser()
        {
            this.Claims = new List<TClaim>();
            this.Logins = new List<TLogin>();
        }
    }
    
    公共类标识用户:IUser
    其中TLogin:IdentityUserLogin
    其中TClaim:IdentityUserClaim
    其中TGroup:IdentityGroup
    其中TGroupRole:IdentityGroupRole
    {
    公共虚拟字符串电子邮件{get;set;}
    公共虚拟布尔值{get;set;}
    公共虚拟字符串密码哈希{get;set;}
    公共虚拟字符串SecurityStamp{get;set;}
    公共虚拟字符串PhoneNumber{get;set;}
    公共虚拟bool phonenumberconfirm{get;set;}
    公共虚拟布尔TwoFactorEnabled{get;set;}
    公共虚拟日期时间?LockoutEndDateUtc{get;set;}
    公共虚拟bool LockoutEnabled{get;set;}
    公共虚拟int AccessFailedCount{get;set;}
    公共虚拟ICollection声明{get;private set;}
    公共虚拟ICollection登录名{get;private set;}
    公共虚拟TGroup组{get;set;}
    公共虚拟密钥Id{get;set;}
    公共虚拟字符串用户名{get;set;}
    公共标识用户()
    {
    this.Claims=新列表();
    this.Logins=新列表();
    }
    }
    
    标识组

    public class IdentityGroup<TKey, TGroupRole> : IGroup<TKey>
        where TGroupRole : IdentityGroupRole<TKey>
    {
        public IdentityGroup()
        {
            Roles = new List<TGroupRole>();
        }
        public TKey Id { get; set; }
        public string Name { get; set; }
        public virtual ICollection<TGroupRole> Roles { get; private set; }
    }
    
    public class IdentityGroup:IGroup
    其中TGroupRole:IdentityGroupRole
    {
    公共标识组()
    {
    角色=新列表();
    }
    公钥Id{get;set;}
    公共字符串名称{get;set;}
    公共虚拟ICollection角色{get;private set;}
    }
    
    群组角色

    public class IdentityGroupRole<TKey>
    {
        public virtual TKey RoleId { get; set; }
        public virtual TKey GroupId { get; set; }
    }
    
    公共类标识组角色
    {
    公共虚拟TKey RoleId{get;set;}
    公共虚拟TKey组ID{get;set;}
    }
    
    IdentityDbContext

    public class IdentityDbContext<TUser, TRole, TKey, TUserLogin, TUserClaim, TGroup, TGroupRole> : DbContext
        where TUser : IdentityUser<TKey, TUserLogin, TUserClaim, TGroup, TGroupRole>
        where TRole : IdentityRole<TKey, TGroupRole>
        where TUserLogin : IdentityUserLogin<TKey>
        where TUserClaim : IdentityUserClaim<TKey>
        where TGroup : IdentityGroup<TKey, TGroupRole>
        where TGroupRole : IdentityGroupRole<TKey>
    {
        private IdentityConfiguration _config;
        public virtual IDbSet<TUser> Users { get; set; }
        public virtual IDbSet<TRole> Roles { get; set; }
        public virtual IDbSet<TGroup> Groups { get; set; }
        public bool RequireUniqueEmail { get; set; }
        public IdentityDbContext()
            : this("DefaultConnection", new IdentityConfiguration())
        {
        }
        public IdentityDbContext(string nameOrConnectionString)
            : this(nameOrConnectionString, new IdentityConfiguration())
        {
        }
        public IdentityDbContext(string nameOrConnectionString, IdentityConfiguration config)
            : base(nameOrConnectionString)
        {
            _config = config;
        }
        public IdentityDbContext(DbConnection existingConnection, DbCompiledModel model, bool contextOwnsConnection)
            : base(existingConnection, model, contextOwnsConnection)
        {
        }
        protected override void OnModelCreating(DbModelBuilder modelBuilder)
        {
            if (modelBuilder == null)
            {
                throw new ArgumentNullException("modelBuilder");
            }
            var user = modelBuilder.Entity<TUser>().ToTable(_config.UserTableName, _config.Schema);
            user.HasMany(u => u.Claims).WithRequired().HasForeignKey(uc => uc.UserId);
            user.HasMany(u => u.Logins).WithRequired().HasForeignKey(ul => ul.UserId);
            user.HasOptional(u => u.Group).WithMany().Map(m => m.MapKey("GroupId"));
            user.Property(u => u.UserName)
                .IsRequired()
                .HasMaxLength(256)
                .HasColumnAnnotation("Index", new IndexAnnotation(new IndexAttribute("UserNameIndex") { IsUnique = true }));
    
            // CONSIDER: u.Email is Required if set on options?
            user.Property(u => u.Email).HasMaxLength(256);
    
            modelBuilder.Entity<TGroupRole>().HasKey((TGroupRole r) => new
            {
                r.GroupId,
                r.RoleId
            }).ToTable(_config.GroupRoleTableName, _config.Schema);
    
            modelBuilder.Entity<TUserLogin>().HasKey((TUserLogin l) => new
            {
                l.LoginProvider,
                l.ProviderKey,
                l.UserId
            }).ToTable(_config.LoginTableName, _config.Schema);
    
            modelBuilder.Entity<TUserClaim>().ToTable(_config.ClaimTableName, _config.Schema);
    
            var role = modelBuilder.Entity<TRole>()
                .ToTable(_config.RoleTableName, _config.Schema);
            role.Property(r => r.Name)
                .IsRequired()
                .HasMaxLength(256)
                .HasColumnAnnotation("Index", new IndexAnnotation(new IndexAttribute("RoleNameIndex") { IsUnique = true }));
            role.HasMany(r => r.Groups).WithRequired().HasForeignKey(ur => ur.RoleId).WillCascadeOnDelete();
    
            var group = modelBuilder.Entity<TGroup>()
                .ToTable(_config.GroupTableName, _config.Schema);
            group.Property(r => r.Name)
                .IsRequired()
                .HasMaxLength(256)
                .HasColumnAnnotation("Index", new IndexAnnotation(new IndexAttribute("GroupNameIndex") { IsUnique = true }));
            group.HasMany(r => r.Roles).WithRequired().HasForeignKey(ur => ur.GroupId).WillCascadeOnDelete();
            //group.HasMany(g => g.Users).WithOptional().Map(m => m.MapKey("GroupId"));
        }
        protected override DbEntityValidationResult ValidateEntity(DbEntityEntry entityEntry, IDictionary<object, object> items)
        {
            if (entityEntry != null && entityEntry.State == EntityState.Added)
            {
                List<DbValidationError> list = new List<DbValidationError>();
                TUser user = entityEntry.Entity as TUser;
                if (user != null)
                {
                    if (this.Users.Any((TUser u) => string.Equals(u.UserName, user.UserName)))
                    {
                        list.Add(new DbValidationError("User", string.Format(CultureInfo.CurrentCulture, IdentityResources.DuplicateUserName, new object[]
                        {
                            user.UserName
                        })));
                    }
                    if (this.RequireUniqueEmail && this.Users.Any((TUser u) => string.Equals(u.Email, user.Email)))
                    {
                        list.Add(new DbValidationError("User", string.Format(CultureInfo.CurrentCulture, IdentityResources.DuplicateEmail, new object[]
                        {
                            user.Email
                        })));
                    }
                }
                else
                {
                    TRole role = entityEntry.Entity as TRole;
                    if (role != null && this.Roles.Any((TRole r) => string.Equals(r.Name, role.Name)))
                    {
                        list.Add(new DbValidationError("Role", string.Format(CultureInfo.CurrentCulture, IdentityResources.RoleAlreadyExists, new object[]
                        {
                            role.Name
                        })));
                    }
                }
                if (list.Any<DbValidationError>())
                {
                    return new DbEntityValidationResult(entityEntry, list);
                }
            }
            return base.ValidateEntity(entityEntry, items);
        }
    }
    
    public类IdentityDbContext:DbContext
    在哪里TUser:IdentityUser
    TRole的位置:IdentityRole
    其中TUserLogin:IdentityUserLogin
    何处TUserClaim:IdentityUserClaim
    其中TGroup:IdentityGroup
    其中TGroupRole:IdentityGroupRole
    {
    私有身份配置_config;
    公共虚拟IDbSet用户{get;set;}
    公共虚拟IDbSet角色{get;set;}
    公共虚拟IDbSet组{get;set;}
    公共bool RequireUniqueEmail{get;set;}
    公共标识YDBContext()
    :此(“默认连接”,ne
    
    public class IdentityGroup<TKey, TGroupRole> : IGroup<TKey>
        where TGroupRole : IdentityGroupRole<TKey>
    {
        public IdentityGroup()
        {
            Roles = new List<TGroupRole>();
        }
        public TKey Id { get; set; }
        public string Name { get; set; }
        public virtual ICollection<TGroupRole> Roles { get; private set; }
    }
    
    public class IdentityGroupRole<TKey>
    {
        public virtual TKey RoleId { get; set; }
        public virtual TKey GroupId { get; set; }
    }
    
    public class IdentityDbContext<TUser, TRole, TKey, TUserLogin, TUserClaim, TGroup, TGroupRole> : DbContext
        where TUser : IdentityUser<TKey, TUserLogin, TUserClaim, TGroup, TGroupRole>
        where TRole : IdentityRole<TKey, TGroupRole>
        where TUserLogin : IdentityUserLogin<TKey>
        where TUserClaim : IdentityUserClaim<TKey>
        where TGroup : IdentityGroup<TKey, TGroupRole>
        where TGroupRole : IdentityGroupRole<TKey>
    {
        private IdentityConfiguration _config;
        public virtual IDbSet<TUser> Users { get; set; }
        public virtual IDbSet<TRole> Roles { get; set; }
        public virtual IDbSet<TGroup> Groups { get; set; }
        public bool RequireUniqueEmail { get; set; }
        public IdentityDbContext()
            : this("DefaultConnection", new IdentityConfiguration())
        {
        }
        public IdentityDbContext(string nameOrConnectionString)
            : this(nameOrConnectionString, new IdentityConfiguration())
        {
        }
        public IdentityDbContext(string nameOrConnectionString, IdentityConfiguration config)
            : base(nameOrConnectionString)
        {
            _config = config;
        }
        public IdentityDbContext(DbConnection existingConnection, DbCompiledModel model, bool contextOwnsConnection)
            : base(existingConnection, model, contextOwnsConnection)
        {
        }
        protected override void OnModelCreating(DbModelBuilder modelBuilder)
        {
            if (modelBuilder == null)
            {
                throw new ArgumentNullException("modelBuilder");
            }
            var user = modelBuilder.Entity<TUser>().ToTable(_config.UserTableName, _config.Schema);
            user.HasMany(u => u.Claims).WithRequired().HasForeignKey(uc => uc.UserId);
            user.HasMany(u => u.Logins).WithRequired().HasForeignKey(ul => ul.UserId);
            user.HasOptional(u => u.Group).WithMany().Map(m => m.MapKey("GroupId"));
            user.Property(u => u.UserName)
                .IsRequired()
                .HasMaxLength(256)
                .HasColumnAnnotation("Index", new IndexAnnotation(new IndexAttribute("UserNameIndex") { IsUnique = true }));
    
            // CONSIDER: u.Email is Required if set on options?
            user.Property(u => u.Email).HasMaxLength(256);
    
            modelBuilder.Entity<TGroupRole>().HasKey((TGroupRole r) => new
            {
                r.GroupId,
                r.RoleId
            }).ToTable(_config.GroupRoleTableName, _config.Schema);
    
            modelBuilder.Entity<TUserLogin>().HasKey((TUserLogin l) => new
            {
                l.LoginProvider,
                l.ProviderKey,
                l.UserId
            }).ToTable(_config.LoginTableName, _config.Schema);
    
            modelBuilder.Entity<TUserClaim>().ToTable(_config.ClaimTableName, _config.Schema);
    
            var role = modelBuilder.Entity<TRole>()
                .ToTable(_config.RoleTableName, _config.Schema);
            role.Property(r => r.Name)
                .IsRequired()
                .HasMaxLength(256)
                .HasColumnAnnotation("Index", new IndexAnnotation(new IndexAttribute("RoleNameIndex") { IsUnique = true }));
            role.HasMany(r => r.Groups).WithRequired().HasForeignKey(ur => ur.RoleId).WillCascadeOnDelete();
    
            var group = modelBuilder.Entity<TGroup>()
                .ToTable(_config.GroupTableName, _config.Schema);
            group.Property(r => r.Name)
                .IsRequired()
                .HasMaxLength(256)
                .HasColumnAnnotation("Index", new IndexAnnotation(new IndexAttribute("GroupNameIndex") { IsUnique = true }));
            group.HasMany(r => r.Roles).WithRequired().HasForeignKey(ur => ur.GroupId).WillCascadeOnDelete();
            //group.HasMany(g => g.Users).WithOptional().Map(m => m.MapKey("GroupId"));
        }
        protected override DbEntityValidationResult ValidateEntity(DbEntityEntry entityEntry, IDictionary<object, object> items)
        {
            if (entityEntry != null && entityEntry.State == EntityState.Added)
            {
                List<DbValidationError> list = new List<DbValidationError>();
                TUser user = entityEntry.Entity as TUser;
                if (user != null)
                {
                    if (this.Users.Any((TUser u) => string.Equals(u.UserName, user.UserName)))
                    {
                        list.Add(new DbValidationError("User", string.Format(CultureInfo.CurrentCulture, IdentityResources.DuplicateUserName, new object[]
                        {
                            user.UserName
                        })));
                    }
                    if (this.RequireUniqueEmail && this.Users.Any((TUser u) => string.Equals(u.Email, user.Email)))
                    {
                        list.Add(new DbValidationError("User", string.Format(CultureInfo.CurrentCulture, IdentityResources.DuplicateEmail, new object[]
                        {
                            user.Email
                        })));
                    }
                }
                else
                {
                    TRole role = entityEntry.Entity as TRole;
                    if (role != null && this.Roles.Any((TRole r) => string.Equals(r.Name, role.Name)))
                    {
                        list.Add(new DbValidationError("Role", string.Format(CultureInfo.CurrentCulture, IdentityResources.RoleAlreadyExists, new object[]
                        {
                            role.Name
                        })));
                    }
                }
                if (list.Any<DbValidationError>())
                {
                    return new DbEntityValidationResult(entityEntry, list);
                }
            }
            return base.ValidateEntity(entityEntry, items);
        }
    }