EnitityFramework обрабатывает многие-ко-многим (*: *) с Collection
s в модели. Итак, у меня есть таблицы SupportEvent
и Employee
с (*: *) отношениями и коллекциями в каждом. Мне нужно добавить сотрудников в службу поддержки на странице Razor.Почему изменения в моих Коллекциях не сохраняются в базе данных?
Первоначально, я делал это не так элегантно, передавая данные отдельно через форму. Когда метод Edit(SupportEvent)
был назван изменениями, внесенными в коллекцию Employees
. Однако, когда я позвонил SaveChanges(supportEvent)
, изменения не были сохранены в db.
Осмотревшись, я обнаружил, что ViewModels - это способ правильно справиться с этим, поэтому я последовал за MVC 5, Entity Framework 6 and Many to Many Relationship : a step by step View Model approach.
Непосредственная «проблема» я нашел, хотя этот путь может быть больше в соответствии с рисунком, когда я вошел в метод Edit()
supportEvent
был точно таким же, и результат SaveChanges()
тоже. Имена и опечатки в стороне, я не вижу нигде, где мой код отличается значимым образом.
Вот мой код:
// ViewModel
public class SupportEventViewModel
{
public SupportEvent SupportEvent { get; set; }
public IEnumerable<SelectListItem> AllEmployees { get; set; }
private List<int> selectedEmployees;
public List<int> SelectedEmployees
{
get
{
if (selectedEmployees == null)
{
selectedEmployees = SupportEvent
.Employees
.Select(m => m.Id)
.ToList();
}
return selectedEmployees;
}
set { selectedEmployees = value; }
}
}
И Edit():
// SupportEventController - Edit()
[HttpPost]
[ValidateAntiForgeryToken]
public ActionResult Edit(SupportEventViewModel model, bool? active)
{
foreach(var e in model.SelectedEmployees)
{
model.SupportEvent.Employees
.Add(db.Employees.Find(e));
}
if (ModelState.IsValid)
{
db.Entry(model.SupportEvent).State = EntityState.Modified;
db.SaveChanges();
return RedirectToAction(((bool)active) ?
"ActiveTicketDetails" : "Details", "Ticket", new { id = model.SupportEvent.TicketId });
}
return View(model);
}
И частичное редактирование:
// The partial view/form
@model ProjectWhiteWave.ViewModels.SupportEventViewModel
@{
Layout = null;
}
<!DOCTYPE html>
<html>
<head>
<meta name="viewport" content="width=device-width" />
<title></title>
</head>
<body>
@Html.AntiForgeryToken()
<div class="form-horizontal">
<h4>SupportEvent</h4>
<hr />
@Html.ValidationSummary(true)
@Html.HiddenFor(model => model.SupportEvent.SupportEventId)
<div class="form-group">
@Html.LabelFor(model => model.SupportEvent.DateOpened, new { @class = "control-label col-md-2" })
<div class="col-md-10">
@Html.EditorFor(model => model.SupportEvent.DateOpened)
@Html.ValidationMessageFor(model => model.SupportEvent.DateOpened)
</div>
</div>
<div class="form-group">
@Html.LabelFor(model => model.SupportEvent.DateClosed, new { @class = "control-label col-md-2" })
<div class="col-md-10">
@Html.EditorFor(model => model.SupportEvent.DateClosed)
@Html.ValidationMessageFor(model => model.SupportEvent.DateClosed)
</div>
</div>
<div class="form-group">
@Html.LabelFor(model => model.AllEmployees, "Technicians", new { @class = "control-label col-md-2" })
<div class="col-md-10">
@Html.ListBoxFor(model => model.SelectedEmployees, Model.AllEmployees)
</div>
</div>
<div class="form-group">
@Html.LabelFor(model => model.SupportEvent.Description, new { @class = "control-label col-md-2" })
<div class="col-md-10">
@Html.EditorFor(model => model.SupportEvent.Description)
@Html.ValidationMessageFor(model => model.SupportEvent.Description)
</div>
</div>
<div class="form-group">
<div class="col-md-offset-2 col-md-10">
<input type="submit" value="Save" class="btn btn-default" />
</div>
</div>
</div>
</body>
</html>
Все вроде бы правильно, и я думаю, это подтверждается тем фактом, что изменения, которые я делаю в представлении, оказываются в методе редактирования. Я знаю, что это не сохраняется, потому что, когда Edit
перенаправляет, и я возвращаюсь на страницу с подробными сведениями, изменений нет.
Что мне не хватает/делает что-то плохое, что предотвращает сохранение данных в базе данных?
Это не похоже на это. Хотя, e, это Id, find находит, что он основан на этом. Когда вызывается «Сохранить», сотрудники добавлены в локальный экземпляр, ModelState действителен, но ничего не записывается. – ChiefTwoPencils