C# 如何准确地从实体列表中删除项而不丢失正确的索引

C# 如何准确地从实体列表中删除项而不丢失正确的索引,c#,for-loop,entity-framework-5,C#,For Loop,Entity Framework 5,我使用的是实体框架5,使用的是代码优先和存储库模式。我的Delete方法如下所示: public virtual void Delete(TEntity entity) { dbSet.Remove(entity); context.SaveChanges(); } 我有一个实体与另一个实体处于1:N关系中: public class Page { public int PageID { get; set; } //other

我使用的是
实体框架5
,使用的是代码优先和
存储库模式
。我的
Delete
方法如下所示:

public virtual void Delete(TEntity entity)
    {
        dbSet.Remove(entity);
        context.SaveChanges();
    }
我有一个实体与另一个实体处于
1:N
关系中:

public class Page
  {
    public int PageID { get; set; }
    //other properties...
    public virtual List<Cell> Cells { get; set; }
  }
每次条件为真且删除一个
单元格时,都会修改列表,如果开始时我有6个单元格且
page.cells.Count
为6,则我的单元格类似于
单元格[0]
单元格[1]
单元格[5]
当我删除一个项目时,列表将更新
页面。Cells.Count
返回5,我的单元格将从0重新索引到4,但现在我的计数器
I
不再与
单元格的索引匹配

我所做的是在每次删除项目时重置计数器:

if (page.Cells[i].RowNum == RowNum)
  {
    unitOfWork.CellRepository.Delete(page.Cells[i]);
    i = -1;
  } 

每次我删除一个项目时,强制循环的
从头开始(换句话说,列表被重新排序)。但我觉得这不是很有效。因为我要处理的数据量很小,所以问题不大,但我想知道还有没有其他(更好/合适的)方法来处理这个问题?

您已经正确地看到,如果您从第一个项目到最后一个项目浏览列表并删除一个项目,可能会遗漏一些项目。您在匹配后将
i
减小1的解决方案是正确的,但不是最优的。更好的解决方案是从列表的末尾遍历到开头,然后索引始终指向正确的项:

for (int i = page.Cells.Count - 1; i >= 0; i--)
{
    if (page.Cells[i].RowNum == RowNum)
    {
        unitOfWork.CellRepository.Delete(page.Cells[i]);
    }
}

这取决于框架如何创建
列表
。如果项目的顺序是确定的,并且在删除项目时不会更改,则可以简单地反转for循环,如下所示:

List<Cell> list = ...;
for (int idx = list.Count - 1; idx >= 0; idx--) {
    if (someCondition(list[idx])) {
        removeItem(list[idx]);
    }
}
List=。。。;
对于(int idx=list.Count-1;idx>=0;idx--){
if(某些条件(列表[idx])){
removeItem(列表[idx]);
}
}
如果列表项的顺序不能保证保持不变,您可以首先找到所有要删除的项,然后在第二次过程中删除它们:

List<Cell> list = ...;
List<Cell> itemsToRemove = new List<Cell>();
foreach (var item in list) {
    if (someCondition(item)) {
        itemsToRemove.Add(item);
    }
}

foreach (var item in itemsToRemove) {
    removeItem(item);
}    
List=。。。;
List itemsToRemove=新列表();
foreach(列表中的变量项){
如果(某些条件(项目)){
itemsToRemove.Add(项目);
}
}
foreach(itemsToRemove中的变量项){
移除项目(项目);
}    

显然,使用可枚举扩展方法可以更好地编写第二个案例。

哦,伙计,另一个谜团被揭开了。我想知道为什么我在某些情况下会看到这种反向变体。。非常感谢,祝你新年快乐!好主意,但有了实体框架,它就足以逆转@xxMUROxx所说的顺序。但在其他类似情况下,这可能会同时发生。非常感谢,祝你新年快乐。
List<Cell> list = ...;
List<Cell> itemsToRemove = new List<Cell>();
foreach (var item in list) {
    if (someCondition(item)) {
        itemsToRemove.Add(item);
    }
}

foreach (var item in itemsToRemove) {
    removeItem(item);
}