Я разрабатываю новый Asp. Net Core API с авторизацией. В моей авторизации пользователи могут иметь несколько ролей. И конечно, одна роль может иметь несколько пользователей.
Вот мои классы:
public class User
{
[Key]
[DatabaseGenerated(DatabaseGeneratedOption.Identity)]
public Guid Id { get; set; }
public ICollection<UserRole> Roles { get; set; }
[NotMapped]
public string Token { get; set; }
}
public class UserRole
{
[JsonIgnore]
public Guid UserId { get; set; }
public User User { get; set; }
public int RoleId { get; set; }
public Role Role { get; set; }
}
public class Role
{
[Key]
[DatabaseGenerated(DatabaseGeneratedOption.Identity)]
public int Id { get; set; }
public string Name { get; set; }
}
ApplicationDbContext:
modelBuilder.Entity<UserRole>()
.HasKey(bc => new { bc.UserId, bc.RoleId });
modelBuilder.Entity<UserRole>()
.HasOne(bc => bc.User)
.WithMany(b => b.Roles)
.HasForeignKey(bc => bc.UserId);
Все это работает, и я получаю правильный вывод из 3 уровней, если я хочу одного пользователя. Но я хочу избавиться от второго уровня. Если я хочу одного пользователя, я хочу возобновить отношения один-много. поэтому мой UserDTO
public class UserDTO
{
public Guid Id { get; set; }
public ICollection<Role> Roles { get; set; }
public string Token { get; set; }
}
ПРИМЕЧАНИЕ: РОЛЬ коллекции вместо UserRole
Но как этого добиться с помощью ядра платформы Entity (3.1) ИЛИ AutoMapper?
И второй вопрос , Если я получу одного пользователя или список пользователей, я получу только 2 уровня. Но если я прошу сначала извлечь все пользовательские роли, я получу 3 уровня. Но у меня есть 2 звонка. Это должен быть один.
-> это работает
public async Task<IEnumerable<User>> GetAll()
{
var ur = await _context.UserRoles.Include(ur => ur.Role).Include(ur => ur.User).ToListAsync();
var users = await _context.Users
.Include(users => users.Roles)
.ToListAsync();
return users;
}
-> это не
public async Task<IEnumerable<User>> GetAll()
{
var users = await _context.Users
.Include(users => users.Roles)
.ToListAsync();
return users;
}
это мои параметры сериализации:
services.AddControllers().AddNewtonsoftJson(options =>
{
options.SerializerSettings.ReferenceLoopHandling = ReferenceLoopHandling.Ignore;
});