[英]MVC 4 and lazy loading: “Collection was modified” error when deleting multiple records
In ASP.NET MVC 4 project, I have a model LeagueMember
: 在ASP.NET MVC 4项目中,我有一个模型
LeagueMember
:
public class LeagueMember
{
[Key, Column(Order = 0)]
public int MemberId { get; set; }
[Key, Column(Order = 1)]
public int LeagueId { get; set; }
public bool? IsActive { get; set; }
public virtual League League { get; set; }
public virtual Member Member { get; set; }
}
In League model, I have: 在联赛模型中,我有:
public virtual ICollection<LeagueMember> LeagueMembers { get; set; }
In the Edit
view of League
controller, I have a dropdown for LeagueMembers
and in its Edit action I am trying to delete existing LeagueMembers and creating new ones: 在
League
控制器的Edit
视图中,我有一个LeagueMembers
的下拉列表,并且在其Edit操作中,我试图删除现有的LeagueMembers并创建新的LeagueMembers:
[HttpPost]
public ActionResult Edit(LeagueMembersViewModel leagueMemberViewModel)
{
if (ModelState.IsValid)
{
var league = leagueMemberViewModel.League;
context.Entry(league).State = EntityState.Modified;
/* without this line the next foreach statement would complain that
League.LeagueMembers is null due to lazy loading..*/
context.Entry(league).Collection("LeagueMembers").Load();
var leagueMembers = leagueMemberViewModel.League.LeagueMembers;
foreach (var leagueMember in leagueMembers)
{
context.LeagueMembers.Remove(leagueMember);
}
foreach (var memberId in leagueMemberViewModel.SelectedMembers)
{
var leagueMember = new LeagueMember { MemberId = memberId, League = league };
context.LeagueMembers.Add(leagueMember);
}
context.SaveChanges();
return RedirectToAction("Index");
}
leagueMemberViewModel.MemberList = new MultiSelectList(context.Members, "Id", "Name", leagueMemberViewModel.SelectedMembers);
return View(leagueMemberViewModel);
}
When executed, the line foreach (var leagueMember in leagueMembers)
complains on second iteration of forloop: 当执行时,
foreach (var leagueMember in leagueMembers)
行foreach (var leagueMember in leagueMembers)
第二次迭代中抱怨:
Collection was modified;
集合已修改; enumeration operation may not execute
枚举操作可能无法执行
Is there a better way to delete bulk records in a one-to-many relationship? 有没有更好的方法来删除一对多关系中的批量记录?
In this case, to Remove All leagueMemberViewModel.League.LeagueMembers
perhaps without iterating through the collection? 在这种情况下, 要删除所有
leagueMemberViewModel.League.LeagueMembers
也许不对集合进行迭代?
Something like, replacing: 诸如此类,替换为:
context.Entry(league).Collection("LeagueMembers").Load();
var leagueMembers = leagueMemberViewModel.League.LeagueMembers;
foreach (var leagueMember in leagueMembers)
{
context.LeagueMembers.Remove(leagueMember);
}
with: 与:
leagueMember.League.LeagueMembers.Remove();
I think your code has some typos. 我认为您的代码有错别字。 For example, it looks like
var league = leagueMember.League
should be var league = leagueMemberViewModel.League
. 例如,它看起来像
var league = leagueMember.League
应该是var league = leagueMemberViewModel.League
。 Reading between the lines I suspect that leagueMembers
is the same as the leagueMembers of the attached league
object. 我怀疑字里行间
leagueMembers
是一样的附着的leagueMembers league
对象。 (That you attach by setting EntityState.Modified
). (通过设置
EntityState.Modified
附加)。
If so, the error is explained by the fact that you loop through a loaded collection and at the same time remove items from it. 如果是这样,则可以通过以下事实来解释该错误:您遍历已加载的集合并同时从中删除项目。 The remedy is simple:
解决方法很简单:
foreach (var leagueMember in leagueMembers.ToArray()) // <= ToArray
which copies the collection to a local array that does not change. 将集合复制到一个不变的本地数组。
As for your second question: no there is no built-in way to do bulk deletes in Entity Framework. 关于第二个问题:在Entity Framework中,没有内置的方法可以进行批量删除。
You cannot modify a collection while iterating through it, the best approach is to use a reverse for loop like this: 您不能在遍历集合时修改集合,最好的方法是使用反向for循环,如下所示:
for (int i = leagueMembers.Count - 1; i >= 0; i--)
{
context.LeagueMembers.Remove(leagueMembers[i]);
}
This is a common .NET error, you can get around this by replacing your foreach
loop with a for
loop: 这是一个常见的.NET错误,您可以通过将
foreach
循环替换for
循环来解决此问题:
for (var i = 0; i < leagueMembers.Count; i++)
{
context.LeagueMembers.Remove(leagueMembers[i]);
}
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.