As the title says, how can I access Role navigation properties in the data context. My User class looks like this
public class AppUser : IdentityUser<int>
{
[Key]
[DatabaseGenerated(DatabaseGeneratedOption.Identity)]
public override int Id { get; set; }
/// <summary>
/// Gets or sets the users first name.
/// </summary>
[MaxLength(32)]
public string FirstName { get; set; }
/// <summary>
/// Gets or sets the users last name.
/// </summary>
[MaxLength(32)]
public string LastName { get; set; }
/// <summary>
/// Gets or sets a value indicating whether this user can be deleted or not.
/// </summary>
public bool Readonly { get; set; }
/// <summary>
/// Gets or sets a value indicating whether this <see cref="AppUser"/> is soft deleted or not.
/// </summary>
public bool Deleted { get; set; }
public virtual ICollection<AppUserRole> AppUserRoles { get; set; } = new List<AppUserRole>();
}
My Role class looks like this
public class AppRole : IdentityRole<int>, IMapFrom<AppRoleDto>
{
[Key]
[DatabaseGenerated(DatabaseGeneratedOption.Identity)]
public override int Id { get; set; }
public virtual ICollection<AppUserRole> AppUserRoles { get; set; } = new List<AppUserRole>();
}
My AppUserRole class looks like this
public class AppUserRole : IdentityUserRole<int>
{
[Key]
[DatabaseGenerated(DatabaseGeneratedOption.Identity)]
public int Id { get; set; }
[ForeignKey(nameof(RoleId))]
public virtual AppRole Role { get; set; }
[ForeignKey(nameof(UserId))]
public virtual AppUser User { get; set; }
}
When I try and add a migration, I see warnings such as “The foreign key property ‘AppUserRole.RoleId1’ was created in shadow state because a conflicting property with the simple name ‘RoleId’ exists in the entity type, but is either not mapped, is already used for another relationship, or is incompatible with the associated primary key type”
In my AccountRepository, the navigations don’t work
public async Task<AppUserDto> GetUser(int id)
{
var entity = await _db.AppUsers
.Include(e => e.AppUserRoles)
.ThenInclude(e => e.Role) // this does not work
.FirstOrDefaultAsync(e => e.Id == id);
if (entity == null)
{
throw new Exception($"User {id} not found.");
}
var dto = _mapper.Map<AppUserDto>(entity);
return dto;
}
My Data Context class includes the following
public class DataContext : IdentityDbContext<AppUser, AppRole, int, IdentityUserClaim<int>, AppUserRole, IdentityUserLogin<int>, IdentityRoleClaim<int>, IdentityUserToken<int>>
{
public DataContext(DbContextOptions<DataContext> options)
: base(options)
{
}
protected override void OnModelCreating(ModelBuilder modelBuilder)
{
modelBuilder.Entity<StateMachine>()
.HasOne(e => e.ToState)
.WithMany()
.OnDelete(DeleteBehavior.NoAction);
var seeder = new Seeder(modelBuilder);
seeder.Seed();
base.OnModelCreating(modelBuilder);
}
public DbSet<AppUser> AppUsers { get; set; }
public DbSet<AppRole> AppRoles { get; set; }
public DbSet<AppUserRole> AppUserRoles { get; set; } . . .
Could anyone tell me how to do this properly ?