У меня есть приложение для хранения информации о консультантах в базе данных. Модель представляет собой модель Entity Framework, а таблицы базы данных являются консультантами с отношениями «один ко многим» с рядом других таблиц (WorkExperiences, Programs, CompetenceAreas и т. Д.). Теперь, когда я хочу создать новый объект консультанта в представлении, я действительно просто хочу передать объект консультанта в качестве модели в представление. Но, например, мне было предложено ( Коллекция сложных дочерних объектов в приложении Asp.Net MVC 3? ), что я не должен этого делать, а вместо этого использовать ViewModels. Во-вторых, и, возможно, в этом причина, я получаю сообщение об ошибке «EntityCollection уже инициализировано», когда я пытаюсь опубликовать объект «Консультант», если использую его в качестве модели в представлении, и причина ошибки, по-видимому, заключается в коллекции объектов, таких как WorkExperiences.
Итак, мой первый вопрос - почему я получаю эту ошибку.
Но что более важно, если бы я вместо этого использовал ViewModel, как бы я сделал это правильно? Потому что я на самом деле что-то пробовал, и получил это работает. Но ... код ужасен. Может кто-нибудь сказать мне, что я должен делать вместо этого, чтобы это работало более чисто?
Позвольте мне показать вам, что у меня есть (это снова работает, но это кошмарный код):
Метод GET Create:
public ActionResult Create()
{
Consultant consultant = new Consultant();
ConsultantViewModel vm = GetViewModel(consultant);
return View(vm);
}
Вспомогательный метод для создания "ViewModel" (если это действительно то, на что должен быть похож ViewModel):
private ConsultantViewModel GetViewModel(Consultant consultant)
{
ConsultantViewModel vm = new ConsultantViewModel();
vm.FirstName = consultant.FirstName;
vm.LastName = consultant.LastName;
vm.UserName = consultant.UserName;
vm.Description = consultant.Description;
vm.Programs = consultant.Programs.ToList();
vm.Languages = consultant.Languages.ToList();
vm.Educations = consultant.Educations.ToList();
vm.CompetenceAreas = consultant.CompetenceAreas.ToList();
vm.WorkExperiences = consultant.WorkExperiences.ToList();
return vm;
}
Метод создания POST:
[HttpPost]
[ValidateInput(false)] //To allow HTML in description box
public ActionResult Create(ConsultantViewModel vm, FormCollection collection)
{
try
{
Consultant consultant = CreateConsultant(vm);
_repository.AddConsultant(consultant);
_repository.Save();
return RedirectToAction("Index");
}
catch
{
return View();
}
}
Вспомогательный метод для создания объекта Консультанта (этот особенно ужасен, когда я должен проверить, что коллекции не равны нулю, на случай, если пользователь решит ничего не добавлять в эти списки ...):
private Consultant CreateConsultant(ConsultantViewModel vm)
{
Consultant consultant = new Consultant();
consultant.Description = vm.Description;
consultant.FirstName = vm.FirstName;
consultant.LastName = vm.LastName;
consultant.UserName = vm.UserName;
if (vm.Programs != null)
foreach (var program in vm.Programs)
consultant.Programs.Add(program);
if (vm.Languages != null)
foreach (var language in vm.Languages)
consultant.Languages.Add(language);
if (vm.Educations != null)
foreach (var education in vm.Educations)
consultant.Educations.Add(education);
if (vm.WorkExperiences != null)
foreach (var workExperience in vm.WorkExperiences)
consultant.WorkExperiences.Add(workExperience);
if (vm.CompetenceAreas != null)
foreach (var competenceArea in vm.CompetenceAreas)
consultant.CompetenceAreas.Add(competenceArea);
return consultant;
}
Итак, снова это работает, но далеко не так чисто, как если бы я мог использовать объект Консультанта напрямую (если бы не эта ошибка "EntityCollection уже инициализирована" ...). Так как я должен это сделать вместо этого?