Как установить свойства навигации перед вставкой в ​​базу данных?

Примечание. Вчера я задал аналогичный вопрос, но с тех пор я перешел от этой проблемы к другой. Хотя это очень тесно связано, я думаю, что это лучше всего выразить в отдельном вопросе.

У меня три модели: Account, AccountType и Person. Я хочу создать единую страницу формы, через которую новая учетная запись с определенным типом учетной записи и с определенной информацией о человеке может быть отправлена ​​​​в базу данных.

public class AccountType
{
    [Key]
    public int AccountTypeID { get; set; }

    [Required]
    public string AccountTypeName { get; set; }
}

public class Person
{
    [Key]
    public int PersonID { get; set; }
    
    // Bunch of properties not relevant to the question here...
}

public class Account
{
    [Key]
    public int AccountID { get; set; }

    [ForeignKey("AccountType")]
    public int AccountTypeID { get; set; }

    [ForeignKey("Person")]
    public int PersonID { get; set; }

    // A few properties here...

    public virtual AccountType AccountType { get; set; }
    public virtual Person Person { get; set; }
}

Поскольку создание новой учетной записи требует от меня вставки в учетную запись, а также в таблицу пользователей, я создал модель представления для обеих этих моделей:

public class Register
{
    public Account Account { get; set; }
    public Person Person { get; set; }
}

В представлении «Регистрация» я просто привязал свойства моделей «Учетная запись» и «Человек» к полям формы. Я также использовал ViewBag для отображения списка типов учетных записей в раскрывающемся списке.

Часть, которую я не понимаю, находится в контроллере POST:

[HttpPost]
[ValidateAntiForgeryToken]
public IActionResult Register(Register Register)
{
    if (ModelState.IsValid) {
        _db.Accounts.Add(Register.Account);
        _db.SaveChanges();
        return View(Register);
    }
    // do something else
}

Проверка ModelState проходит успешно после комментирования параметра Nullable в файле проекта. Однако Register.Account имеет нулевые свойства:

Как установить свойства навигации перед вставкой в ​​базу данных?

Все значения, которые я привязывал в представлении «Реестр», устанавливаются корректно, но свойства навигации (Register.Account.AccountType и Register.Account.Person) я ни к чему не привязывал, так как не знал, что с ними делать.

Теперь я не могу вставить в базу данных приведенный выше код, потому что получаю ошибку ограничения внешнего ключа Person. Кажется, что Register.Account не может иметь нулевых значений для своих свойств навигации Person или AccountType. Судя по всему, они должны быть установлены (или, по крайней мере, свойство Person должно быть установлено).

Я знаю, что могу установить эти свойства навигации вручную в контроллере. Для Person я могу написать что-то вроде этого перед сохранением в БД: Register.Account.Person = Register.Person, и я также могу придумать что-то для AccountTypes, чтобы придать ему правильное значение. Я проверил это, и он вставляется в базу данных.

Но это не кажется мне правильным подходом. Мне кажется, что должен быть лучший, более правильный способ прояснить отношения модели или таблицы к .NET перед вставкой в ​​базу данных.

Кто-нибудь знает лучший способ?

PS: я использую .NET 6.

Ваша модель представления не должна раскрывать вашу модель данных, поскольку MVC с радостью привяжет все свойства.

Jeremy Lakeman 23.03.2022 03:52

Я понимаю. Итак, должна ли моя модель представления просто служить хранилищем для свойств, которые я хочу захватить (привязать) из формы, чтобы в методе действия POST я мог создавать новые экземпляры моделей Account и Person, а затем заполнять их данные из модели представления? Хотя я, вероятно, мог бы понять это, было бы полезно увидеть пример кода.

Skjervoy 23.03.2022 04:07

Есть сторонние инструменты, которые могут помочь вам в этом. например dotnettutorials.net/lesson/automapper-in-c-sharp

Jeremy Lakeman 23.03.2022 04:10
Стоит ли изучать PHP в 2023-2024 годах?
Стоит ли изучать PHP в 2023-2024 годах?
Привет всем, сегодня я хочу высказать свои соображения по поводу вопроса, который я уже много раз получал в своем сообществе: "Стоит ли изучать 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
3
29
1
Перейти к ответу Данный вопрос помечен как решенный

Ответы 1

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

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

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