尝试添加到集合时获取“Collection was modified”异常
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循环并在form.Links中添加“ToList()”。在所有情况下都抛出相同的异常。我在网站的其他部分使用这个确切的模式没有问题,这就是为什么这是如此令人沮丧。这也适用于“创建”。该问题仅影响“编辑”操作。
其他相关代码:
[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; }
}
更新
更多信息:添加到集合中......即使在循环之外也会引发相同的错误。这会给任何人一个想法吗?
答案 0 :(得分:0)
请改为尝试:
var lsEvents = form.Event.Links.ToList();
foreach (var resource in form.Links)
{
resource.EventID = form.Event.ID;
if (!assignedIds.Contains(resource.ResourceTypeID))
lsEvents.Add(resource);
}
foreach (var resource in form.Event.Links)
{
if (!selectedIds.Contains(resource.ResourceTypeID))
lsEvents.Remove(resource);
}
并根据要求使用lsEvents
。这将解决您的问题。
答案 1 :(得分:0)
您可以在添加条目之前使用LINQ过滤掉条目。
public void UpdateLinks(EventViewModel form)
{
var selectedIds = form.Links.Select(r => r.ResourceTypeID).ToArray();
var assignedIds = form.Event.Links.Select(r => r.ResourceTypeID).ToArray();
foreach (var resource in form.Links
.Where(r=> !assignedIds.Contain(r.ResourceTypeID)).ToArray())
{
resource.EventID = form.Event.ID;
form.Event.Links.Add(resource);
}
foreach (var resource in form.Event.Links
.Where(r=> !selectedIds.Contain(r.ResourceTypeID)).ToArray())
{
form.Event.Links.Remove(resource);
}
}
在这两种方法中,我们在枚举和添加之前过滤资源。您无法同时枚举和添加。
答案 2 :(得分:0)
您无法修改您枚举的集合(例如,每个集合)。
您需要循环一次以获取要添加和/或删除的项目,然后在第一个循环外的第二个循环中添加或删除所有项目。
E.g:
Dim coll = New List(of String)({"1", "2", "3", "4", "6"})
dim coll2 = New List(of String)({"5", "8", "9", "2"})
Dim removeItems as new list(of String)()
For Each item in coll
For Each item2 in coll2
If item2 = item
removeItems.Add(item)
end if
Next item2
Next item
' remove the items gathered
For each itemToRemove in removeItems
coll.Remove(itemToRemove)
Next itemToRemove
可以采用更好的方式,但这显示了错误的要点。您无法更改正在循环的集合。
答案 3 :(得分:0)
不确定究竟是什么负责解决问题,但升级到Visual Studio 2013 Express(来自2010 Professional),并安装ASP.Net 4.5 / IIS8后,即使此应用程序继续以ASP.Net 4.0为目标,我不再遇到问题,原帖中使用的代码按原样运行。
也许这是由ASP.Net框架的某个版本或旧版本的IIS引起的?