当前位置: 首页 > 知识库问答 >
问题:

添加到集合时修改了集合

朱越
2023-03-14

尝试添加到集合时出现“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循环并添加“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; }
}

更新

更多信息:添加到集合中...即使在循环之外也会抛出同样的错误。这给任何人一个想法吗?

共有3个答案

闾丘博
2023-03-14

您不能修改正在枚举的集合(例如,每个集合)。

您需要循环一次以获取要添加和/或删除的项目,然后在第一个循环之外的第二个循环中添加或删除所有项目。

例如:

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

可以用更好的方法来完成,但这说明了错误的要点。无法更改正在循环的集合。

蒲昀
2023-03-14

在添加条目之前,可以使用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);
    }
}

在这两种方法中,我们都在枚举和添加之前过滤资源。您不能同时枚举和添加。

李利
2023-03-14

试试这个:

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。这将解决您的问题。

 类似资料:
  • 我们在Google Firestore中有一个收藏。 我们是否可以在一条语句中添加一个包含数据的文档和此新文档下的子集合?

  • 我正在从一个可观察的列表中设置一个ListView,该列表有另一个集合的输入(在本例中是一个链表)。因此,我在这个答案中找到了如何使列表视图的项从中移除(我不太确定它们是否也从ObservableList中移除),那么还有什么可能的方法可以在两个集合(即ObservableList和原始集合)中进行修改呢? 下面是一段代码:

  • 问题内容: 假设我有一个Integer列表,并且我在列表上使用Java 8 forEach方法将其值加倍。说我有以下代码: 至于forEach方法,请使用Consumer并调用它接受方法。我在上面的代码运行后打印列表,原始列表没有变化。 据我了解,Stream不会改变源,但在这里我只是在每个元素上调用accept方法。 谢谢你在advace 问题答案: forEach不更改列表的原因归结为规范:

  • 我正在向我的主干集合中添加一个项目,如下所示: 我在MyCollection中覆盖了同步,如下所示: 但是,似乎在add之后不会调用sync,add成功执行并触发“add”事件。我错过什么了吗?还是这是正确的行为?

  • 本文向大家介绍JavaScript 向集合添加值,包括了JavaScript 向集合添加值的使用技巧和注意事项,需要的朋友参考一下 示例 要将值添加到集合,请使用以下方法:.add() 如果该值已存在于集合中,则不会再次添加,因为集合包含唯一值。 请注意,该方法本身返回集合,因此您可以将添加调用链接在一起:.add()            

  • 我已经解决了如何合并两个XML文件并修改匹配的属性。 我现在正在努力解决如果file1中不存在file2节点,如何添加file2节点(基于属性名) 这是我拥有的xsl文件: 我找到了如何使用XSLT合并两个xml文件,但无法解决如何将提议解决方案应用于我的xsl。有人能帮忙吗?