C# 我在foreach期间收到“集合已修改;枚举操作可能无法执行”
我需要确认我的方法,我正在使用EF和ASP.NET MVC,并且我正在尝试根据用户选择(即根据他们已检查/未检查的内容)删除实体 为此,我将查看从表单中通过复选框传递的ID,匹配数据库中的ID,然后首先添加任何新的ID,然后删除任何不匹配的ID 以下是我最初拥有的代码:C# 我在foreach期间收到“集合已修改;枚举操作可能无法执行”,c#,asp.net,asp.net-mvc-3,entity-framework-4.1,C#,Asp.net,Asp.net Mvc 3,Entity Framework 4.1,我需要确认我的方法,我正在使用EF和ASP.NET MVC,并且我正在尝试根据用户选择(即根据他们已检查/未检查的内容)删除实体 为此,我将查看从表单中通过复选框传递的ID,匹配数据库中的ID,然后首先添加任何新的ID,然后删除任何不匹配的ID 以下是我最初拥有的代码: [HttpPost] public ActionResult Edit(int id, FormCollection collection, VMinstanceRole vmodel) {
[HttpPost]
public ActionResult Edit(int id, FormCollection collection, VMinstanceRole vmodel)
{
try
{
var instancerole = db.instanceRoles.Find(id);
if (ModelState.IsValid)
{
UpdateModel<instanceRole>(instancerole, "instanceRole");
var keys = instancerole.rights.Select( c => c.Id);
foreach (var pid in vmodel.selectedId.Except(keys))
{
var right = new right { Id = pid };
db.rights.Attach(right);
instancerole.rights.Add(right);
}
foreach (var pid in keys.Except(vmodel.selectedId))
{
var right = instancerole.rights.Where(c => c.Id == pid).Single();
instancerole.rights.Remove(right);
}
db.SaveChanges();
}
// TODO: Add update logic here
return RedirectToAction("Index");
}
catch (InvalidCastException e)
{
return View();
}
}
但是,出现了以下错误:集合被修改;枚举操作不能执行
因此,为了解决这个问题,我决定保留一个单独的列表,并在之后根据该列表将其删除,以克服错误:
[HttpPost]
public ActionResult Edit(int id, FormCollection collection, VMinstanceRole vmodel)
{
try
{
var instancerole = db.instanceRoles.Find(id);
List<right> removeList = new List<right>();
if (ModelState.IsValid)
{
UpdateModel<instanceRole>(instancerole, "instanceRole");
var keys = instancerole.rights.Select( c => c.Id);
foreach (var pid in vmodel.selectedId.Except(keys))
{
var right = new right { Id = pid };
db.rights.Attach(right);
instancerole.rights.Add(right);
}
foreach (var pid in keys.Except(vmodel.selectedId))
{
var right = instancerole.rights.Where(c => c.Id == pid).Single();
removeList.Add(right);
}
foreach (var right in removeList)
{
instancerole.rights.Remove(right);
}
db.SaveChanges();
}
// TODO: Add update logic here
return RedirectToAction("Index");
}
catch (InvalidCastException e)
{
return View();
}
}
这似乎有效,但我不确定我是否做了正确的事情。主要是因为我在做另一个循环。有没有更好的方法来解决这个问题,或者这已经足够好了 在使用foreach枚举时无法编辑集合的原因在这里已经有足够的文档记录,只需检查侧边的“相关”链接,如果知道您不能这样做,您可以使用一个简单的for循环,并在删除项后修改索引-这允许您维护一个循环
for (int i = 0; i < max; i++) {
//if removing an item
//manipulate the index as desired...
i--;
}
在使用foreach枚举时无法编辑集合的原因在这里已经有足够的文档记录,只需检查侧边的“相关”链接即可,在知道不能这样做的情况下,您可以使用一个简单的for循环,并在删除项后修改索引-这允许您维护一个循环
for (int i = 0; i < max; i++) {
//if removing an item
//manipulate the index as desired...
i--;
}
你找到了一个标准的解决方案。另一个可行的解决方案是在生成keys对象的LINQ操作上调用ToList:这样做将断开keys与instanceroles集合的连接,允许对原始集合进行任意独立修改。您找到了一个标准解决方案。另一个可行的解决方案是在生成keys对象的LINQ操作上调用ToList:这样做将断开keys与instanceroles集合的连接,允许对原始集合进行任意独立修改。尝试以下操作:
foreach (var pid in keys.Except(vmodel.selectedId).ToList())
{
var right = instancerole.rights.Where(c => c.Id == pid).Single();
instancerole.rights.Remove(right);
}
删除第一项时,foreach循环中枚举的枚举数将被释放。请尝试以下操作:
foreach (var pid in keys.Except(vmodel.selectedId).ToList())
{
var right = instancerole.rights.Where(c => c.Id == pid).Single();
instancerole.rights.Remove(right);
}
您在foreach循环中枚举的枚举器将在您删除第一项时被释放。嗨,伊利亚,谢谢您的回复,我明白您的意思。这感觉比我拥有的好多了。谢谢你的回答,我明白你的意思。这感觉比我拥有的好多了。感谢thaks dasblinkenlight的回复我有点困惑是否应该将ToList存储在另一个变量中,但我想我现在已经得到了它。谢谢你给我指点方向。嗨dasblinkenlight,thaks,谢谢你的回答我有点困惑是否应该将ToList存储在另一个变量中,但我想我现在已经知道了。谢谢你给我指路。