Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/263.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 修改IEnumerable神秘,什么是修改我的IEnumerable?_C#_Extension Methods_Ienumerable - Fatal编程技术网

C# 修改IEnumerable神秘,什么是修改我的IEnumerable?

C# 修改IEnumerable神秘,什么是修改我的IEnumerable?,c#,extension-methods,ienumerable,C#,Extension Methods,Ienumerable,我已经编写了一个扩展方法来向(EF)EntityCollection添加项。我得到一个有趣的错误,说我的IEnumerable(“items”)集合在foreach中的第一个循环之后被修改了。当我将items转换为items.ToList()时(如下面的代码中所示),它可以正常工作 我完全理解执行ToList()将生成foreach随后将操作的项目的副本 我不明白的是,当我对IEnumerable进行foreach时,是什么在修改它 更新:不知何故,items变量似乎与collections变量

我已经编写了一个扩展方法来向(EF)EntityCollection添加项。我得到一个有趣的错误,说我的IEnumerable(“items”)集合在foreach中的第一个循环之后被修改了。当我将items转换为items.ToList()时(如下面的代码中所示),它可以正常工作

我完全理解执行ToList()将生成foreach随后将操作的项目的副本

我不明白的是,当我对IEnumerable进行foreach时,是什么在修改它

更新:不知何故,items变量似乎与collections变量相同

更新2:我认为集合和实体可能会受到EF实体跟踪的影响,但我仍然无法理解为什么

用法:

ssp.serviceares.ReplaceCollection(model.serviceares)

以下是我的扩展方法:

    public static void AddOrUpdate<TEntity>(this EntityCollection<TEntity> collection, IEnumerable<TEntity> items)
        where TEntity : EntityObject, IProjectIdentity<int>, new()
    {
        foreach (var item in items.ToList())
            collection.AddOrUpdate(item);
    }

    public static void AddOrUpdate<TEntity>(this EntityCollection<TEntity> collection, TEntity item)
        where TEntity : EntityObject, IProjectIdentity<int>, new()
    {
        if (item.ID > 0 && collection.Any(c => c.ID == item.ID))
            collection.Remove(collection.First(c => c.ID == item.ID));
        // For now, the Remove NEVER gets hit

        collection.Add(item);
    }
publicstaticvoidaddorupdate(此EntityCollection集合,IEnumerable项)
其中tenty:EntityObject,iprojectdentity,new()
{
foreach(items.ToList()中的var item)
收集、添加或更新(项目);
}
公共静态无效添加或更新(此EntityCollection集合,TEntity项)
其中tenty:EntityObject,iprojectdentity,new()
{
if(item.ID>0&&collection.Any(c=>c.ID==item.ID))
collection.Remove(collection.First(c=>c.ID==item.ID));
//现在,移除永远不会被击中
集合。添加(项目);
}

您正在迭代的集合中删除。

也许
EntityCollection
不喜欢有人接管它的元素?因此,当您添加到
集合
时,项目将从
项目
中删除


或者可能是
items==collection
我创建了以下示例代码:

internal class Program
    {
        private static void Main(string[] args)
        {
            var one = new List<string> {"Adam", "John"};

            var two = new List<string> {"Adam", "Houldsworth"};

            one.AddOrUpdate(two);

            Console.Read();
        }
    }

    static class Extensions
    {
        public static void AddOrUpdate(this IList<string> collection, IEnumerable<string> items)
        {
            foreach (var item in items.ToList())
                collection.AddOrUpdate2(item);
        }

        public static void AddOrUpdate2(this IList<string> collection, string item)
        {
            if (collection.Any(c => c == item))
                collection.Remove(collection.First(c => c == item));

            collection.Add(item);
        }
    }
因此,从我看到的情况来看,您必须使用与两个参数相同的集合调用此扩展方法


如果是,则
Remove
Add
都会改变集合并导致此异常。

可能是第一个项目始终是新项目,因此默认情况下ID设置为某个初始值。然后将其添加到集合中,让EntityFramework生成一个新ID并将其分配给第一个添加的项

然后可能是EntityCollection认为它已经更改了,因为它使用ID在内部进行排序或其他操作。因此,foreach操作(可能使用相同的列表)抛出异常。这也是为什么Adam Houldsworth证明的测试用例没有给出问题

EntityCollection客户=新EntityCollection();
EntityCollection<Customer> customers = new EntityCollection<Customer>();
Customer newCustomer = new Customer() {ID = 0};
customers.Add(newCustomer);
customers.AddOrUpdate(customers);
客户newCustomer=newCustomer(){ID=0}; customers.Add(newCustomer); customers.AddOrUpdate(客户);
Remove
修改它,add也修改它。@vcsjones虽然这是真的,但在这种情况下它并不是那么简单。在您的情况下,
items==collection
吗?您正在从您要访问的集合中添加/删除项(第一个方法为foreach块中的每个项目调用第二个方法,第二个方法是加载/删除内容)。第一个:如何将“项目”与“集合”相同?第二个:删除实际上从未命中,我将更新帖子。但迭代是通过不同的集合(项目)进行的事实上,我对此进行了升级,但在尝试时,这不会导致任何问题。谢谢,但无论是否使用.ToList(),此功能都有效。这仅仅是因为集合和项目确实是不同的对象。我认为我的集合对象可能会受到EF跟踪机制的影响,将再次更新帖子。:-)@sebastiaan是的,我注意到它在没有
ToList
的情况下也能工作,但我保持它与您提供的代码类似,以演示问题的来源。
one.AddOrUpdate(one);
EntityCollection<Customer> customers = new EntityCollection<Customer>();
Customer newCustomer = new Customer() {ID = 0};
customers.Add(newCustomer);
customers.AddOrUpdate(customers);