Эти две сущности являются отношением один-ко-многим (строится на основе кода, свободно бегущего API).
public class Parent
{
public Parent()
{
this.Children = new List<Child>();
}
public int Id { get; set; }
public virtual ICollection<Child> Children { get; set; }
}
public class Child
{
public int Id { get; set; }
public int ParentId { get; set; }
public string Data { get; set; }
}
В моем контроллере WebApi у меня есть действия по созданию родительской сущности (которая работает нормально) и обновлению родительской сущности (которая имеет некоторые проблемы). Действие обновления выглядит так:
public void Update(UpdateParentModel model)
{
//what should be done here?
}
В настоящее время у меня есть две идеи:
Получить гусеничный родительский объект с именем
existing
поmodel.Id
и присвоению значения вmodel
один за другим к объекту. Это звучит глупо. И вmodel.Children
я не знаю, какой ребенок новый, какой ребенок изменен (или даже удален).Создайте новую родительскую сущность через
model
и прикрепите ее к DbContext и сохраните. Но как DbContext может узнать о состоянии детей (новое добавление / удаление / изменение)?
Как правильно реализовать эту функцию?
источник
Ответы:
Поскольку модель, которая публикуется в контроллере WebApi, отсоединяется от любого контекста Entity Framework (EF), единственным вариантом является загрузка графа объекта (родительского элемента, включая его дочерние элементы) из базы данных и сравнение того, какие дочерние элементы были добавлены, удалены или удалены. обновлено. (Если вы не будете отслеживать изменения с помощью собственного механизма отслеживания во время отсоединенного состояния (в браузере или где-либо еще), что, на мой взгляд, является более сложным, чем следующее.) Это может выглядеть так:
...CurrentValues.SetValues
может принимать любой объект и отображать значения свойств в присоединенную сущность на основе имени свойства. Если имена свойств в вашей модели отличаются от имен в сущности, вы не можете использовать этот метод и должны присваивать значения одно за другим.источник
existingParent.Children.Add(newChild)
потому что тогда при поиске существующего Linux linq будет возвращаться недавно добавленная сущность, и эта сущность будет обновлена. Вам просто нужно вставить во временный список, а затем добавить.existingChild
.Where(c => c.ID == childModel.ID && c.ID != default(int))
Я возился с чем-то вроде этого ...
который вы можете позвонить с чем-то вроде:
К сожалению, этот тип не работает, если в дочернем типе есть свойства коллекции, которые также необходимо обновить. Рассматривая попытку решить эту проблему, передав IRepository (с базовыми методами CRUD), который будет отвечать за собственный вызов UpdateChildCollection. Позвонил бы в репо вместо прямых звонков в DbContext.Entry.
Не знаю, как все это будет работать в масштабе, но не уверен, что еще нужно делать с этой проблемой.
источник
toAdd.ForEach(i => (selector(dbItem) as ICollection<Tchild>).Add(i.Value));
должен решить n -> n проблему.Хорошо, парни. Я получил этот ответ один раз, но потерял его по пути. абсолютная пытка, когда ты знаешь, что есть лучший способ, но не можешь вспомнить или найти его! Это очень просто. Я только что проверил это несколькими способами.
Вы можете заменить весь список новым! Код SQL будет удалять и добавлять объекты по мере необходимости. Не нужно беспокоиться об этом. Не забудьте включить детскую коллекцию или не кубики. Удачи!
источник
Если вы используете EntityFrameworkCore, вы можете сделать следующее в своем действии контроллера после публикации ( метод Attachure рекурсивно присоединяет свойства навигации, включая коллекции):
Предполагается, что каждый обновленный объект имеет все свойства, установленные и предоставленные в данных поста от клиента (например, не будет работать для частичного обновления объекта).
Вы также должны убедиться, что вы используете новый / выделенный контекст базы данных платформы сущностей для этой операции.
источник
Вот как я решил эту проблему. Таким образом, EF знает, что добавить, а что обновить.
источник
Есть несколько проектов, которые облегчают взаимодействие между клиентом и сервером в том, что касается сохранения всего графа объектов.
Вот два, на которые вы хотели бы взглянуть:
Оба вышеуказанных проекта распознают отключенные объекты, когда они возвращаются на сервер, обнаруживают и сохраняют изменения и возвращают данные, затронутые клиентом.
источник
Просто доказательство концепции
Controler.UpdateModel
не будет работать правильно.Полный класс здесь :
источник
@ Чарльз Макинтош действительно дал мне ответ для моей ситуации в том, что переданная модель была отсоединена. Для меня то, что в конечном итоге сработало, это сначала сохранить переданную модель ... затем продолжить добавлять детей, как я уже был раньше:
источник
Для разработчиков VB.NET Используйте этот универсальный саб, чтобы отметить дочернее состояние, простое в использовании
источник
источник
источник
Вот мой код, который работает просто отлично.
источник