После исследования всего дня и ночи у меня есть кое-что, что в данный момент работает. Однако я не уверен, что я действительно понимаю, что происходит со свойствами навигации и связями сущностей, поэтому я обеспокоен тем, что мой код может вызвать проблемы в будущем. Мне пришлось вручную установить свойства навигации на «EntityState.Modified». Моя модель может в конечном итоге иметь много уровней навигационных объектов и коллекций. Есть ли более простой способ обновить связанные объекты? Если нет более простого способа, хорошо ли этот подход?
Вот вид модели
public class ViewModel {
public ViewModel() { }
public ViewModel(Context context) {
this.Options = new SelectList(context.Options, "Id", "Name");
}
public Parent Parent { get; set; }
public SelectList Options { get; set; }
}
классы сущностей
public class Parent {
public virtual int Id { get; set; }
public virtual string Name { get; set; }
public virtual ChildOne ChildOne { get; set; }
public virtual ChildTwo ChildTwo { get; set; }
}
public class ChildOne {
public virtual int Id { get; set; }
public virtual string Name { get; set; }
public virtual Parent Parent { get; set; }
public virtual int OptionId { get; set; }
public virtual Option Option { get; set; }
}
public class ChildTwo {
public virtual int Id { get; set; }
public virtual string Name { get; set; }
public virtual Parent Parent { get; set; }
public virtual int OptionId { get; set; }
public virtual Option Option { get; set; }
}
public class Option {
public int Id { get; set; }
public string Name { get; set; }
public virtual ICollection<ChildOne> ChildrenOnes { get; set; }
public virtual ICollection<ChildTwo> ChildrenTwos { get; set; }
}
контекст
public class Context : DbContext {
public DbSet<Parent> Parents { get; set; }
public DbSet<ChildOne> ChildrenOnes { get; set; }
public DbSet<ChildTwo> ChildrenTwos { get; set; }
public DbSet<Option> Options { get; set; }
protected override void OnModelCreating(DbModelBuilder modelBuilder) {
base.OnModelCreating(modelBuilder);
modelBuilder.Entity<Parent>()
.HasOptional(x => x.ChildOne)
.WithOptionalPrincipal(x => x.Parent);
modelBuilder.Entity<Parent>()
.HasOptional(x => x.ChildTwo)
.WithOptionalPrincipal(x => x.Parent);
}
}
Контроллер
private Context db = new Context();
public ActionResult Edit() {
ViewModel viewmodel = new ViewModel(db);
viewmodel.Parent = db.Parents.Find(1);
return View(viewmodel);
}
public void Save(Parent parent) {
if (ModelState.IsValid) {
db.Entry(parent).State = EntityState.Modified;
db.Entry(parent.ChildOne).State = EntityState.Modified;
db.Entry(parent.ChildTwo).State = EntityState.Modified;
db.SaveChanges();
}
}
и просмотр
@model MvcApp7.Models.ViewModel
<div id="Parent">
@Html.HiddenFor(model => model.Parent.Id)
@Html.TextBoxFor(model => model.Parent.Name)
<div id="ChildOne">
@Html.HiddenFor(model => model.Parent.ChildOne.Id)
@Html.TextBoxFor(model => model.Parent.ChildOne.Name)
@Html.DropDownListFor(model => model.Parent.ChildOne.OptionId, Model.Options)
</div>
<div id="ChildTwo">
@Html.HiddenFor(model => model.Parent.ChildTwo.Id)
@Html.TextBoxFor(model => model.Parent.ChildTwo.Name)
@Html.DropDownListFor(model => model.Parent.ChildTwo.OptionId, Model.Options)
</div>
</div>
<input id="SaveButton" type="button" value="save" />
<script type="text/javascript">
$('#SaveButton').click(function () {
var data = $('input, select, textarea').serialize();
$.post('@Url.Action("Save")', data, function () { });
});
</script>