Вставка EF Core в таблицу «многие ко многим»

Я создал свою модель пользователя с помощью Razor Pages, и на странице создания я хочу вставить роль пользователя в соединительную таблицу UserRoles.

это моя модель

[Table("Users")]
public class User
{
    public User()
    {
        IsActivo = true;          
    }

    public int Id { get; set; }

    [Required]
    [Display(Prompt = "Username")]
    public string Username { get; set; }
    [Display(Name = "Último Acesso")]
    public DateTime? DataSessao { get; set; }
    [Display(Name = "Activo")]
    public bool IsActivo { get; set; } 
    public Colaborador Colaborador { get; set; }

    public ICollection<UserRoles> UserRoles { get; set; }
}

и это модель создания

public class CreateModel : PageModel
{
    private readonly HutIS.Models.HutISContext _context;

    public CreateModel(HutISContext context)
    {
        _context = context;
    }

    public IActionResult OnGet()
    {
        DepartamentosOptions = _context.Departamento.Select(d =>
              new SelectListItem
                  {
                       Value = d.Id.ToString(),
                       Text = d.Nome
                  }).ToList();


        RolesOptions = _context.Roles.Select(d =>
                  new SelectListItem
                      {
                         Value = d.Id.ToString(),
                         Text = d.Type
                       }).ToList();

        return Page();
    }

    [BindProperty]
    public User User { get; set; }
    public List<SelectListItem> DepartamentosOptions { get; set; }
    public List<SelectListItem> RolesOptions { get; set; }

    public async Task<IActionResult> OnPostAsync()
    {
        if (!ModelState.IsValid)
        {
            return Page();
        }

        _context.User.Add(User);

        await _context.SaveChangesAsync();

        return RedirectToPage("./Index");
    }
}

на html

<div class = "form-group">
    <label asp-for = "User.UserRoles" class = "control-label"></label>
    <select asp-for = "User.UserRoles" asp-items = "Model.RolesOptions" class = "form-control form-control-sm">
        <option value = "">Selecione um Departamento...</option>
    </select>
    <span asp-validation-for = "User.UserRoles" class = "text-danger"></span>
</div>

Я не совсем уверен, как я могу это сделать, конечно, здесь я получаю исключение, но как я могу связать UserRoles, если это коллекция в User ?

РЕДАКТИРОВАТЬ

Я решил проблему исключения, она была связана со свойствами модели. Теперь проблема в том, что в таблицу UserRoles ничего не вставляется, я не совсем уверен, как это сделать, поскольку у пользователя нет свойства навигации для UserRoles, в отличие от отделов.

Вставка EF Core в таблицу «многие ко многим»

как видите отношения правильные

с какой проблемой/исключением вы столкнулись?

Aarif 03.04.2019 13:19

Обновленный пост, исключение устранено, но ничего не вставлено

Jackal 03.04.2019 13:31

кажется, что во внешнем интерфейсе вы должны назначать существующие роли пользователей пользователю, где логика, которая может создавать новые роли пользователей?

Aarif 03.04.2019 13:39

Это на другой странице, роль модели была создана с использованием Razor CRUD. Я знаю, что мог бы сделать это отдельно, но я думал, что можно назначить роль пользователю при создании пользователя. Есть уже созданные роли.

Jackal 03.04.2019 13:42

так что, в этом звонке роли будут просто назначены пользователю? Вы просмотрели вставленные данные в БД, чтобы проверить, правильно ли назначены роли, и если у вас возникли проблемы при создании UserRole, возможно, вы можете поделиться этим кодом

Aarif 03.04.2019 13:43

это цель, вставьте идентификатор пользователя и идентификатор роли в соединительную таблицу. но ничего не вставляется. Я думаю, что мне нужно связать его с моделью как массив и вставить первый индекс, но я не уверен

Jackal 03.04.2019 13:44

SelectListItem заполняется, имеет ли это значение primary key?

Aarif 03.04.2019 13:46

Правильно, вы можете видеть в коде на странице Метод Get, также добавлено изображение отношений, они верны

Jackal 03.04.2019 13:48

Я отредактировал вопрос, чтобы отразить, что это действительно вопрос EF Core, а не ASP.Net. Вам необходимо явно обновить ролевые отношения, это не произойдет бесплатно. См. docs.microsoft.com/en-us/ef/core/saving/related-data для получения дополнительной информации.

Brad Patton 03.04.2019 20:20
Стоит ли изучать PHP в 2026-2027 годах?
Стоит ли изучать PHP в 2026-2027 годах?
Привет всем, сегодня я хочу высказать свои соображения по поводу вопроса, который я уже много раз получал в своем сообществе: "Стоит ли изучать PHP в...
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
В JavaScript одним из самых запутанных понятий является поведение ключевого слова "this" в стрелочной и обычной функциях.
Приемы CSS-макетирования - floats и Flexbox
Приемы CSS-макетирования - floats и Flexbox
Здравствуйте, друзья-студенты! Готовы совершенствовать свои навыки веб-дизайна? Сегодня в нашем путешествии мы рассмотрим приемы CSS-верстки - в...
Тестирование функциональных ngrx-эффектов в Angular 16 с помощью Jest
В системе управления состояниями ngrx, совместимой с Angular 16, появились функциональные эффекты. Это здорово и делает код определенно легче для...
Концепция локализации и ее применение в приложениях React ⚡️
Концепция локализации и ее применение в приложениях React ⚡️
Локализация - это процесс адаптации приложения к различным языкам и культурным требованиям. Это позволяет пользователям получить опыт, соответствующий...
Пользовательский скаляр GraphQL
Пользовательский скаляр GraphQL
Листовые узлы системы типов GraphQL называются скалярами. Достигнув скалярного типа, невозможно спуститься дальше по иерархии типов. Скалярный тип...
0
9
782
1
Перейти к ответу Данный вопрос помечен как решенный

Ответы 1

Ответ принят как подходящий

Для <select multiple = "multiple" asp-for = "User.RoleIds" asp-items = "Model.RolesOptions" class = "form-control form-control-sm"> он будет отправлять значение RoleId вместо объекта роли, вам нужно определить public ICollection<int> UserRoleIds { get; set; }, чтобы принимать RoleId.

Выполните следующие действия:

  1. Определите ViewModel с помощью UserRoleIds

    public class UserVM
    {
        public UserVM()
        {
            IsActivo = true;
        }
    
        public int Id { get; set; }
    
        [Required]
        [Display(Prompt = "Username")]
        public string Username { get; set; }
        [Display(Name = "Último Acesso")]
        public DateTime? DataSessao { get; set; }
        [Display(Name = "Activo")]
        public bool IsActivo { get; set; }
    
        public ICollection<int> RoleIds { get; set; }
    }
    
  2. Модель бритвы

    public class CreateModel : PageModel
    {
        private readonly TestRazorContext _context;
    
        public CreateModel(TestRazorContext context)
        {
            _context = context;
        }
    
        public IActionResult OnGet()
        {
            RolesOptions = _context.Role.Select(d =>
                    new SelectListItem
                    {
                        Value = d.Id.ToString(),
                        Text = d.Type
                    }).ToList();
            return Page();
        }
    
        [BindProperty]
        public UserVM User { get; set; }
        public List<SelectListItem> RolesOptions { get; set; }
    
        public async Task<IActionResult> OnPostAsync()
        {
            if (!ModelState.IsValid)
            {
                return Page();
            }
            //create user
            var user = new User {
                Username = User.Username,
                //rest properties
            };
            _context.User.Add(user);
            await _context.SaveChangesAsync();
            //set user role
            var userRoles = new List<UserRoles>();
            foreach (var roleId in User.RoleIds)
            {
                userRoles.Add(new UserRoles
                {
                    UserId = user.Id,
                    RoleId = roleId
                });
            }
            _context.UserRole.AddRange(userRoles);
            await _context.SaveChangesAsync();
            return RedirectToPage("./Index");
        }
    }
    
  3. бритвенный вид

    <form method = "post">
        <div class = "form-group">
            <label asp-for = "User.Username" class = "control-label"></label>
            <input asp-for = "User.Username" />
        </div>    
        <div class = "form-group">
            <label asp-for = "User.RoleIds" class = "control-label"></label>
            <select multiple = "multiple" asp-for = "User.RoleIds" asp-items = "Model.RolesOptions" class = "form-control form-control-sm">
                <option value = "">Selecione um Departamento...</option>
            </select>
            <span asp-validation-for = "User.RoleIds" class = "text-danger"></span>
        </div>
        <input type = "submit" value = "Submit"/>
    </form>
    

Другие вопросы по теме