Модели со списком подмоделей, как добавить, удалить - PullRequest
0 голосов
/ 03 апреля 2019

У меня есть 3 модели (Брифинг, Ligne, Voie), у каждой модели есть список подмоделей. как управлять им в виде добавления / удаления элемента?

public class Briefing
    {
        public int Id { get; private set; }
        public Guid GuidBriefing { get; set; }
        public int Version { get; set; }
        public List<Ligne> Lignes { get; set; }
        public string Libelle { get; set; }
        public string Description { get; set; }
    }

public class Ligne
    {
        public int Id { get; set; }
        public string Libelle { get; set; }
        public List<VoieObject> Voies { get; set; }
    }

public class VoieObject
   {
        public int Id { get; set; }
        public string Libelle { get; set; }
        public int Vitesse { get; set; }
        public string PointKilometrique { get; set; }
        public string PointKilometriqueFin { get; set; }
}

Я использую Entity Framework и хотел бы узнать, как я могу управлять этими моделями, используя MVC 5 для добавления или удаления элемента в списке для каждой модели.

для примера: для брифинга, как я могу добавить новый элемент "Ligne" в список с видом.

Для информации не могу использовать этот способ написания:

@Html.LabelFor(model => model.FavouriteMovies[i].Title)
    @Html.EditorFor(model => model.FavouriteMovies[i].Title)
    @Html.ValidationMessageFor(model => model.FavouriteMovies[i].Title)

Я должен использовать:

<label for="FavouriteMovies_0__Title">Title</label>
<input id="FavouriteMovies_0__Title" name="FavouriteMovies[0].Title" type="text" value="" />
<span class="field-validation-error">The Title field is required.</span>

Я также проверил эту статью: Добавить элемент в список из представления и передать контроллеру в MVC5

Но я не знаю, будет ли JSON, сгенерированный при отправке формы, правильно сохранять мои данные.

Спасибо за вашу помощь и вашу доброту:)

1 Ответ

0 голосов
/ 04 апреля 2019

Во-первых, чтобы избавить себя от множества головных болей, не передавайте объекты сущностей на ваше усмотрение.Да, будет много примеров, демонстрирующих это, но он предоставляет данные, которые вы не хотите, чтобы пользователи клиентов знали, это приводит к тому, что загружается из базы данных больше данных и идет по проводам, чем необходимо, и это продвигает ленивый, неподтвержденное сохранение.(То есть принять сущность обратно, присоединить ее к контексту, установить состояние Modified и SaveChanges.) Не доверять абсолютно ничему, что возвращается клиентом, без тщательной проверки.

Возможно, вам придется разделить свой вопроси уточнить моменты с примерами того, что вы пытались сравнить с тем, что вы ожидаете, потому что в зависимости от того, что вы хотите сделать, существуют различные подходы.Например, вы можете «добавить» дочернюю сущность (создать новую дочернюю и связать ее с сущностью) или связать существующую сущность с другой.Например: для фильма я, возможно, захочу «добавить» рецензию, которая потребует от пользователя ввода некоторых полей и сохранения в фильме.В качестве альтернативы я мог бы создать резервирование и захотеть «связать» фильм.Это включает в себя поиск соответствующего экземпляра фильма, а не его создание.

На высоком уровне, с веб-приложениями, жизненный цикл редактирования объекта будет выглядеть примерно так:

  • Загрузитьсущность из контекста.
  • Сопоставление с моделью представления, отображающей только данные, необходимые для представления.
  • Если это что-то вроде резервирования с фильмами, то оно будет включать коллекцию MovieViewModels, котораяможет содержать MovieId, Name и любые другие детали, которые могут отображаться.
  • Возвращение модели представления для просмотра.

для сценариев ассоциации, например, когда мы создаем новое резервирование иЕсли вы хотите связать фильмы, просмотр также будет вызывать через Fetch / Ajax и т. д. для поиска совпадений или списка доступных записей.Опять же, эти вызовы будут следовать следующим шагам.Клиентское приложение будет связывать выбранные фильмы и т. Д. С резервированием, это может включать добавление или удаление ассоциаций с фильмами.При сохранении мы разбили бы операцию на конкретные действия, такие как UpdateReservation или CancelReservation, например.

При обновлении резервирования будет принята модель представления (или другая специально созданная модель представления для обновления), а затем: - Убедитесь, что модель представления применима к пользователю, вошедшему в систему в данный момент. - Проверьте правильность данных, переданных.- Если что-то не так с данными, запишите детали и прекратите сеанс.(Подозреваемый взлом пользователя / взлом) - Загрузите объект из контекста с помощью идентификатора, включая дочерние ссылки, которые будут потенциально обновлены.(быстро) - убедитесь, что данные не устарели (проверьте версию метки времени / строки, записанную в модели представления с момента чтения объекта, чтобы убедиться, что она соответствует текущей метке времени объекта. Если это не так, это значит, что кто-то другой изменил этозапись после этого сеанса прочитайте его, поэтому вы можете попросить пользователя просмотреть и повторно применить изменения)

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

var childIds = viewModel.Children.Select(x => x.ChildId).ToList(); // we only care about the IDs.
var existingChildIds = entity.Children.Select(x => x.ChildId).ToList(); 
var childIdsToAdd = childIds.Except(existingChildIds);

var childEntitiesToAdd = context.Children.Where(x => childIdsToAdd.Contains(x.ChildId).ToList();
var childEntitiesToRemove = entity.Children.Where(x => !childIds.Contains(x.ChildId));

foreach(var child in childEntitiesToRemove)
  entity.Children.Remove(child);

entity.Children.AddRange(childEntitiesToAdd);

Когда дело доходит до добавления и удаления новых дочерних объектов, мы можем рассматривать их как отдельные действия.Зачастую создание нового объекта включает в себя запись большего количества данных, чем мы обычно видим на родительском уровне, поэтому это обычно делается в отдельном представлении, таком как всплывающее диалоговое окно или другая страница.Это может использовать отдельное действие в представлении, чтобы создать нового потомка и связать его с родителем по идентификатору.Исходная модель представления для родительского элемента может быть обновлена ​​или обновлена ​​с сервера после завершения операции.

Таким образом, действие контроллера для выполнения чего-либо вроде записи обзора может выглядеть следующим образом:

[Post]
public async Task<JsonResult> AddMovieReview(int movieId, string comment, int rating)
{
   // validate movie exists, and rating is valid, i.e. 1-5
   // create new Review entity using comment and rating.
   // load movie from context using movie ID.
   // add review to the movie.
   // save changes.
   // return a view model with a result (success/failure) and perhaps the new avg. rating for the movie.
}

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

...