Entity Framework: не может быть настроен для класса «xxx», потому что это производный тип - PullRequest
0 голосов
/ 16 февраля 2019

Я получил эту ошибку при попытке добавить таблицу «AppUserRoles» самостоятельно для доступа к UserRoles от пользователя, например:

from u in _userManager.Users.Where(x => x.UserRoles "contain" "some codition here")

И я получил эту ошибку:

Aключ не может быть настроен на «AppUserRoles», потому что это производный тип.Ключ должен быть настроен для корневого типа «IdentityUserRole».Если вы не намеревались включить «IdentityUserRole» в модель, убедитесь, что оно не включено в свойство DbSet вашего контекста, не указано в вызове конфигурации для ModelBuilder или не указано в свойстве навигации для включенного типав модели.

Это мой предыдущий код, он работает нормально:

builder.Entity<IdentityUserRole<Guid>>().ToTable("AppUserRoles")
.HasKey(x => new { x.RoleId, x.UserId });

---> И я перехожу на это:

Мойкласс пользователя

[Table("AppUsers")]
public class AppUser : IdentityUser<Guid>, IDateTracking, ISwitchable
{
    public virtual ICollection<AppUserRoles> UserRoles { get; set; }
}

Мой класс роли

[Table("AppRoles")]
public class AppRole : IdentityRole<Guid>
{
    public virtual ICollection<AppUserRoles> UserRoles { get; set; }
}

Мой класс appUserRole:

[Table("AppUserRoles")]
public class AppUserRoles : IdentityUserRole<Guid>
{

    public virtual AppUser User { get; set; }
    public virtual AppRole Role { get; set; }
}

Мой DbContextClass

public class AppDbContext : IdentityDbContext<AppUser, AppRole, Guid>
{
    public AppDbContext(DbContextOptions options) : base(options)
    {
    }
    public DbSet<AppUser> AppUsers { get; set; }
    public DbSet<AppRole> AppRoles { get; set; }
    public DbSet<AppUserRoles> AppUserRoles { get; set; }

    protected override void OnModelCreating(ModelBuilder builder)
    {
        #region Identity Config

        builder.Entity<IdentityUserClaim<Guid>>().ToTable("AppUserClaims").HasKey(x => x.Id);

        builder.Entity<IdentityUserLogin<Guid>>().ToTable("AppUserLogins").HasKey(x => x.UserId);

        builder.Entity<AppUserRoles>(userRole =>
        {
            userRole.HasKey(ur => new { ur.UserId, ur.RoleId });

            userRole.HasOne(ur => ur.Role)
                .WithMany(r => r.UserRoles)
                .HasForeignKey(ur => ur.RoleId)
                .IsRequired();

            userRole.HasOne(ur => ur.User)
                .WithMany(r => r.UserRoles)
                .HasForeignKey(ur => ur.UserId)
                .IsRequired();
        });

        builder.Entity<IdentityUserToken<Guid>>().ToTable("AppUserTokens")
           .HasKey(x => new { x.UserId });

        #endregion Identity Config

    }

    public override int SaveChanges()
    {
        var modified = ChangeTracker.Entries().Where(e => e.State == EntityState.Modified || e.State == EntityState.Added);

        foreach (EntityEntry item in modified)
        {
            var changedOrAddedItem = item.Entity as IDateTracking;
            if (changedOrAddedItem != null)
            {
                if (item.State == EntityState.Added)
                {
                    changedOrAddedItem.DateCreated = DateTime.Now;
                }
                changedOrAddedItem.DateModified = DateTime.Now;
            }
        }
        return base.SaveChanges();
    }
}

public class DesignTimeDbContextFactory : IDesignTimeDbContextFactory<AppDbContext>
{
    public AppDbContext CreateDbContext(string[] args)
    {
        IConfiguration configuration = new ConfigurationBuilder()
            .SetBasePath(Directory.GetCurrentDirectory())
            .AddJsonFile("appsettings.json").Build();
        var builder = new DbContextOptionsBuilder<AppDbContext>();
        var connectionString = configuration.GetConnectionString("DefaultConnection");
        builder.UseSqlServer(connectionString);
        return new AppDbContext(builder.Options);
    }
}

Это мойфайл запуска:

services.AddDbContext<AppDbContext>(options =>

options.UseSqlServer(Configuration.GetConnectionString("DefaultConnection"),
            o => o.MigrationsAssembly("YayoiApp.Data.EF")), 
            ServiceLifetime.Scoped);

Пожалуйста, дайте мне несколько советов, я уже много исследовал, но не нашел решения.Спасибо.

1 Ответ

0 голосов
/ 18 февраля 2019

Для пользовательских IdentityUserRole<Guid> вам необходимо изменить DbContext на

public class ApplicationDbContext : IdentityDbContext<AppUser
    , AppRole
    , Guid
    , IdentityUserClaim<Guid>
    , AppUserRoles
    , IdentityUserLogin<Guid>
    , IdentityRoleClaim<Guid>
    , IdentityUserToken<Guid>>
{

, а затем зарегистрировать его в Startup.cs

services.AddIdentity<AppUser, AppRole>()
    .AddDefaultUI(UIFramework.Bootstrap4)
    .AddEntityFrameworkStores<ApplicationDbContext>();

UseCase:

public class HomeController : Controller
{
    private readonly UserManager<AppUser> _userManager;
    private readonly RoleManager<AppRole> _roleManager;
    public HomeController(UserManager<AppUser> userManager
        , RoleManager<AppRole> roleManager)
    {
        _userManager = userManager;
        _roleManager = roleManager;
    }
    public async Task<IActionResult> Index()
    {
        var userName = "Tom";
        var passWord = "1qaz@WSX";
        var appUser = new AppUser
        {
            UserName = userName
        };
        await _userManager.CreateAsync(appUser, passWord);
        var roleName = "Admin";
        await _roleManager.CreateAsync(new AppRole { Name = roleName });
        await _userManager.AddToRoleAsync(appUser, roleName);
        var roles = appUser.UserRoles;
        return View();
    }
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...