У меня большие трудности с созданием сложного объекта. У меня есть модель EF с таблицей консультантов, которая имеет отношение «один ко многим» с рядом других таблиц. Я хотел использовать объект «Консультант» в качестве модели, как есть, потому что это было бы очень просто и легко (и как это сделано в учебном пособии NerdDinner), как я делал с другими объектами, которые не имели отношения один ко многим , Проблема заключается в том, что эти отношения вызывают эту ошибку: «EntityCollection уже инициализирован», когда я пытаюсь выполнить публикацию в метод Create.
Несколько человек посоветовали мне использовать ViewModel вместо этого, и я опубликовал вопрос об этом ( ViewModels и отношения один-ко-многим с Entity Framework в MVC? ), потому что я не совсем понимаю Это. Проблема в том, что код становится невероятно нелепым ... Это далеко от простоты, которую я до сих пор ценил в MVC.
В этом вопросе я забыл упомянуть, что, кроме метода Create, метод Edit использует тот же метод CreateConsultant (имя может вводить в заблуждение, оно фактически заполняет объект Консультант). И поэтому, чтобы не добавлять дополнительные, скажем, «Программы», добавленные при редактировании, мне нужно было еще больше усложнить этот метод. Итак, теперь это выглядит так:
private Consultant CreateConsultant(ConsultantViewModel vm, Consultant consultant) //Parameter Consultant needed because an object may already exist from Edit method.
{
consultant.Description = vm.Description;
consultant.FirstName = vm.FirstName;
consultant.LastName = vm.LastName;
consultant.UserName = User.Identity.Name;
if (vm.Programs != null)
for (int i = 0; i < vm.Programs.Count; i++)
{
if (consultant.Programs.Count == i)
consultant.Programs.Add(vm.Programs[i]);
else
consultant.Programs.ToList()[i] = vm.Programs[i];
}
if (vm.Languages != null)
for (int i = 0; i < vm.Languages.Count; i++)
{
if (consultant.Languages.Count == i)
consultant.Languages.Add(vm.Languages[i]);
else
consultant.Languages.ToList()[i] = vm.Languages[i];
}
if (vm.Educations != null)
for (int i = 0; i < vm.Educations.Count; i++)
{
if (consultant.Educations.Count == i)
consultant.Educations.Add(vm.Educations[i]);
else
consultant.Educations.ToList()[i] = vm.Educations[i];
}
if (vm.WorkExperiences != null)
for (int i = 0; i < vm.WorkExperiences.Count; i++)
{
if (consultant.WorkExperiences.Count == i)
consultant.WorkExperiences.Add(vm.WorkExperiences[i]);
else
consultant.WorkExperiences.ToList()[i] = vm.WorkExperiences[i];
}
if (vm.CompetenceAreas != null)
for (int i = 0; i < vm.CompetenceAreas.Count; i++)
{
if (consultant.CompetenceAreas.Count == i)
consultant.CompetenceAreas.Add(vm.CompetenceAreas[i]);
else
consultant.CompetenceAreas.ToList()[i] = vm.CompetenceAreas[i];
}
string uploadDir = Server.MapPath(Request.ApplicationPath) + "FileArea\\ConsultantImages\\";
foreach (string f in Request.Files.Keys)
{
var filePath = Path.Combine(uploadDir, Path.GetFileName(Request.Files[f].FileName));
if (Request.Files[f].ContentLength > 0)
{
Request.Files[f].SaveAs(filePath);
consultant.Image = filePath;
}
}
return consultant;
}
Это абсурд, и, вероятно, это из-за моей некомпетентности, но мне нужно знать, как это сделать правильно. Просто ответа «использовать ViewModel», очевидно, будет недостаточно, потому что именно это и привело меня к этой проблеме с самого начала. Мне нужна простота простого объекта-сущности в качестве модели, но без ошибки «EntityCollection уже был инициализирован». Как мне обойти это?
Конечно, если я просто неправильно выполняю стратегию ViewModel, предложения по этому вопросу тоже приветствуются, но в основном я хочу знать, что вызывает эту ошибку, если я делаю это простым способом "NerdDinner", простым объектом. Также имейте в виду, что рассматриваемый вид предназначен только для авторизованных пользователей сайта. Я хотел бы сделать это "правильным" способом, но если использование ViewModels подразумевает наличие кода, который так сложно поддерживать, я воздержусь от него ...
Пожалуйста, помогите!
UPDATE:
Оказывается, этот код даже не работает. Я только что проверил после вызова Edit для обновления значений, и он не обновляет их. Так что работает только часть Создать.
Эта часть не работает:
consultant.Programs.ToList()[i] = vm.Programs[i];
У меня была догадка, что я не смог использовать ToList и обновить элемент в EntityCollection. Но это делает это еще сложнее. Так что теперь я не знаю, как сделать это с сущностью напрямую, что я бы предпочел (см. Выше). И я не знаю, как заставить все это работать с ViewModel, не говоря уже о том, чтобы очистить его ...
Есть идеи? Здесь должно быть что-то действительно не так, и я надеюсь, что кто-то заметит, как я только что пропустил что-то простое, что переворачивает весь этот код с ног на голову!