MVC и EF4 CTP модель привязки и сохранения иерархической модели - PullRequest
2 голосов
/ 24 января 2011

У меня проблемы с нахождением четкого ответа на мою ситуацию при поиске переполнения стека и Google, надеюсь, кто-то может указать мне правильное направление.

Моя ситуация Я хочу иметь возможность использовать одну форму редактирования (в одном представлении) для обновления иерархического объекта глубиной 3 уровня с использованием ASP.NET MVC 3 и Entity Framework 4 CTP (Code-first) - модель состоит из служб, у которого может быть много вариантов обслуживания, которые, в свою очередь, могут иметь много предметов инвентаря.

Я ожидал, что смогу использовать связыватель модели MVC по умолчанию (через TryUpdateModel) для:

  1. Обновление существующей записи «Служба»
  2. Добавление / обновление / удаление записей «Service Option» (прикрепленных к Сервису) в зависимости от опубликованных значений
  3. Добавление / обновление / удаление записей «Инвентаризация» (прикрепленных к каждому варианту обслуживания) в зависимости от опубликованных значений

Моя модель

    [Bind(Include="Name, ServiceOptions")]
public class Service {
    [Key]
    public int ServiceID { get; set; }      
    public string Name { get; set; }        
    public DateTime DateCreated { get; set; }
    public virtual ICollection<ServiceOption> ServiceOptions { get; set; }
}

[Bind(Include="ServiceOptionID, Description, Tags")]
public class ServiceOption {
    [Key]
    public int ServiceOptionID { get; set; }
    public int ServiceID { get; set; }  /* parent id reference */
    public string Description { get; set; }
    public virtual ICollection<Inventory> InventoryItems { get; set; }
}


[Bind(Include = "InventoryID, Description")]
public class Inventory {
    [Key]
    public int InventoryID { get; set; }
    public int ServiceOptionID { get; set; }  /* parent id reference */
    public string Description { get; set; }
}

Идеальный метод управления:

    [HttpPost]
public ActionResult EditService(int id) {
    Service service = db.Services.Single(s => s.ServiceID == id);
    TryUpdateModel(service); // automatically updates child and grandchild records

    if (ModelState.IsValid) {               
        db.SaveChanges();
        return RedirectToAction("Index");
    }
    return View(service);
}

Есть ли способ осуществить эту утопическую мечту или я лаю не на том дереве? Я открыт для использования другой технологии (такой как обычный EF4, Automapper и т. Д.)

Заранее спасибо!

1 Ответ

0 голосов
/ 24 января 2011

Только с моделью для подшивки по умолчанию?Наверное, нет.

С кастомным?Вероятно.

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

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

Кроме того, ИМХО, этот метод также плох, потому что вы позволяете фрагменту кода отвечать за отображение значений httpтакже диктуйте, как объекты должны быть сохранены.Это плохой ход.Я считаю операции удаления довольно священным действием, и его не следует оставлять наедине с ModelBinder.Без мягкого удаления или регистрации удаление объектов следует считать «серьезным делом».

...