EF Core为用户添加角色

时间:2018-03-24 23:47:40

标签: c# entity-framework-core

我想包含用户角色列表。

var users = Users
                .Include(u => u.UserRoles)
                .ToList()

我遵循了许多建议来解决问题,但没有一个对我有用:

所以可能其他人可能处于相同的情况。

Startup.cs

    services.AddIdentity<User, Role>()
        .AddEntityFrameworkStores<ApiDbContext>()
        .AddDefaultTokenProviders()
        ;//.AddUserStore<UserStore<User, Role, ApiDbContext, Guid>>()//, IdentityUserClaim<Guid>, UserRole, IdentityUserLogin<Guid>, IdentityUserToken<Guid>, IdentityRoleClaim<Guid>>>()
         //.AddRoleStore<RoleStore<Role, ApiDbContext, Guid>>();//, UserRole, IdentityRoleClaim < Guid >>> ();

[注意]:在评论中,有许多不同的尝试使迁移工作失败

Role.cs

 public class Role : IdentityRole<Guid>
 {
        public virtual ICollection<UserRole> UserRoles { get; } = new List<UserRole>();
 }

User.cs

public class User : IdentityUser<Guid>, IEntity
{
    public virtual ICollection<UserRole> UserRoles { get; } = new List<UserRole>();
}

UserRole.cs

public class UserRole : IdentityUserRole<Guid>
{
    public virtual User User { get; }
    public virtual Role Role { get; }
}

ApiDbContext.cs

public class ApiDbContext : IdentityDbContext<User, Role, Guid, IdentityUserClaim<Guid>, UserRole, IdentityUserLogin<Guid>, IdentityRoleClaim<Guid>, IdentityUserToken<Guid>>
{
        protected override void OnModelCreating(ModelBuilder builder)
    {
        builder.Entity<User>()
            .HasMany(e => e.UserRoles)
            .WithOne()
            .HasForeignKey(e => e.UserId)
            .IsRequired()
            .OnDelete(DeleteBehavior.Cascade);

        builder.Entity<UserRole>()
            .HasOne(e => e.User)
            .WithMany(e => e.UserRoles)
            .HasForeignKey(e => e.UserId);

        builder.Entity<UserRole>()
            .HasOne(e => e.Role)
            .WithMany(e => e.UserRoles)
            .HasForeignKey(e => e.RoleId);

        base.OnModelCreating(builder);
    }

每次我运行“添加迁移”时,无论建议如何,我总是有:

        migrationBuilder.CreateTable(
            name: "AspNetUserRoles",
            columns: table => new
            {
                UserId = table.Column<Guid>(nullable: false),
                RoleId = table.Column<Guid>(nullable: false),
                RoleId1 = table.Column<Guid>(nullable: true),
                UserId1 = table.Column<Guid>(nullable: true)
            },
            constraints: table =>
            {
                table.PrimaryKey("PK_AspNetUserRoles", x => new { x.UserId, x.RoleId });
                table.ForeignKey(
                    name: "FK_AspNetUserRoles_AspNetRoles_RoleId",
                    column: x => x.RoleId,
                    principalTable: "AspNetRoles",
                    principalColumn: "Id",
                    onDelete: ReferentialAction.Cascade);
                table.ForeignKey(
                    name: "FK_AspNetUserRoles_AspNetRoles_RoleId1",
                    column: x => x.RoleId1,
                    principalTable: "AspNetRoles",
                    principalColumn: "Id",
                    onDelete: ReferentialAction.Restrict);
                table.ForeignKey(
                    name: "FK_AspNetUserRoles_AspNetUsers_UserId",
                    column: x => x.UserId,
                    principalTable: "AspNetUsers",
                    principalColumn: "Id",
                    onDelete: ReferentialAction.Cascade);
                table.ForeignKey(
                    name: "FK_AspNetUserRoles_AspNetUsers_UserId1",
                    column: x => x.UserId1,
                    principalTable: "AspNetUsers",
                    principalColumn: "Id",
                    onDelete: ReferentialAction.Restrict);
            });

Role1和User1不应该在那里。

我正在使用:

<PackageReference Include="Microsoft.EntityFrameworkCore.Tools" Version="2.0.2" />

是否有人知道如何解决此问题?

2 个答案:

答案 0 :(得分:0)

这不是特定于EF核心,但希望可以帮助您: https://msdn.microsoft.com/en-us/library/jj591620(v=vs.113).aspx#Anchor_3

在我看来,你过分地定义了多对多的关系。除非您在UserRoles表上需要其他属性,否则无需直接引用它。我会简化你的ApiDbContext:

public class ApiDbContext : IdentityDbContext<User, Role, Guid, IdentityUserClaim<Guid>, UserRole, IdentityUserLogin<Guid>, IdentityRoleClaim<Guid>, IdentityUserToken<Guid>>
{
        protected override void OnModelCreating(ModelBuilder builder)
    {
        builder.Entity<User>()
            .HasMany(e => e.Role)
            .WithMany(r => r.User)
            .OnDelete(DeleteBehavior.Cascade);

        base.OnModelCreating(builder);
    }
}

答案 1 :(得分:0)

尝试将setter添加到UserRole的属性。

public class UserRole : IdentityUserRole<Guid>
{
    public virtual User User { get; set; }
    public virtual Role Role { get; set; }
}

如果您只需要阅读它,则可以添加私有构造函数。

public class UserRole : IdentityUserRole<Guid>
{
    private User _user;
    private Role _role;

    private UserRole()
    {
    }

    public UserRole(User user, Role role)
    {
        _user = user;
        _role = role;
    }

    public virtual User User => _user;
    public virtual Role Role => _role;
}

但是,您需要在dbcontext中配置私有字段。

protected override void OnModelCreating(ModelBuilder modelBuilder)
{
    modelBuilder.Entity<UserRole>().Property(u => u.User).HasField("_user");
    modelBuilder.Entity<UserRole>().Property(u => u.Role).HasField("_role");
}
相关问题