Получение «Коллекция была изменена» исключение при попытке добавить к коллекцииКоллекция была изменена при добавлении в коллекцию
public void UpdateLinks(EventViewModel form)
{
var selectedIds = form.Links.Select(r => r.ResourceTypeID).ToList();
var assignedIds = form.Event.Links.Select(r => r.ResourceTypeID).ToList();
foreach (var resource in form.Links)
{
resource.EventID = form.Event.ID;
if (!assignedIds.Contains(resource.ResourceTypeID))
form.Event.Links.Add(resource);
}
foreach (var resource in form.Event.Links.ToList())
{
if (!selectedIds.Contains(resource.ResourceTypeID))
form.Event.Links.Remove(resource);
}
}
Проблема именно с «Добавить» методом. Если я прокомментирую эту часть, исключение не будет выбрано. Важно отметить, что я уже пытался переписать foreach как цикл for и добавить «ToList()» в form.Links. Такое же исключение выбрасывается во всех случаях. Я использую этот точный шаблон на других частях сайта без проблем, поэтому это так расстраивает. Это также работает над «Создать». Проблема влияет только на действие «Изменить».
Другое соответствующий код:
[HttpPost]
public ActionResult Edit(EventViewModel form, HttpPostedFileBase[] eventFiles)
{
if (ModelState.IsValid)
{
eventsService.UpdateEvent(form.Event);
eventsService.UpdateManufacturerTags(form);
eventsService.UpdateFiles(form, eventFiles);
eventsService.UpdateLinks(form);
eventsService.Save();
return RedirectToAction("Details", new { id = form.Event.ID });
}
return View(form);
}
public class EventViewModel : ContentLeftViewModel
{
public Event Event { get; set; }
public string[] SelectedManufacturers { get; set; }
public MultiSelectList Manufacturers { get; set; }
public IList<EventResource> Files { get; set; }
public IList<EventResource> Links { get; set; }
public EventViewModel()
{
SelectedManufacturers = new string[0];
Files = new List<EventResource>();
Links = new List<EventResource>();
}
}
public class Event
{
[Key]
public int ID { get; set; }
[Required]
public string Title { get; set; }
[Required]
[DisplayName("Start Time")]
[DisplayFormat(ApplyFormatInEditMode = true, DataFormatString = "{0:M/d/yyyy h:mm tt}")]
public DateTime? StartTime { get; set; }
[Required]
[DisplayName("End Time")]
[DisplayFormat(ApplyFormatInEditMode = true, DataFormatString = "{0:M/d/yyyy h:mm tt}")]
public DateTime? EndTime { get; set; }
public string Venue { get; set; }
public string Address { get; set; }
public string City { get; set; }
public string State { get; set; }
public string Zip { get; set; }
[AllowHtml]
[DataType(DataType.MultilineText)]
public string Description { get; set; }
[DisplayName("Registration Link")]
public string RegistrationUrl { get; set; }
public virtual IList<Manufacturer> Manufacturers { get; set; }
public virtual IList<EventResource> Files { get; set; }
public virtual IList<EventResource> Links { get; set; }
//public IEnumerable<EventResource> Resources
//{
// get { return Files.Concat(Links); }
//}
public string StartDate
{
get { return StartTime.Value.ToShortDateString(); }
}
public string StartTimeOnly
{
get { return StartTime.Value.ToShortTimeString(); }
}
public string EndDate
{
get { return EndTime.Value.ToShortDateString(); }
}
public string EndTimeOnly
{
get { return EndTime.Value.ToShortTimeString(); }
}
public Event()
{
Manufacturers = new List<Manufacturer>();
Files = new List<EventResource>();
Links = new List<EventResource>();
}
}
public class EventResource
{
[Key, Column(Order = 0)]
public int EventID { get; set; }
[Key, Column(Order = 1)]
public int ResourceTypeID { get; set; }
[Key, Column(Order = 2)]
public string Path { get; set; }
public virtual Event Event { get; set; }
public virtual ResourceType Type { get; set; }
}
UPDATE
Некоторые подробнее: Добавление к коллекции вообще ... даже вне цикла бросает ту же ошибку. Это дает кому-то идею?
Не рекомендуется изменять коллекцию, когда вы выполняете итерацию через foreach.see, если простой для цикла подходит для цели. –
. Каждая коллекция .Net генерирует исключение, если вы попытаетесь изменить его во время итерации через него - не если это цикл для каждого цикла, или если вы получили итератор и делаете это «вручную» (в цикле for или while). Попробуйте использовать For-Loop, как предложено выше, или создайте временную коллекцию с данными, которые вы хотите удалить или добавить впоследствии. – peter
В других частях сайта я успешно использовал одно и то же решение для разных типов объектов. Вы правы, но добавляете «ToList()», чтобы создать новый список, чтобы избежать этой проблемы в этих других случаях. Я попробую предложения ниже. –