我编写了一个扩展方法来向(EF)EntityCollection添加项目。我收到一个有趣的错误,说我的IEnumerable(“items”)集合在foreach的第一个循环之后被修改了。当我将项目转换为items.ToList()(如下面的代码中),它工作正常。
我完全理解,做ToList()会生成foreach将在其上运行的项目的副本。
我不明白的是当我对它进行预测时修改IEnumerable的内容。
更新:不知何故,似乎items变量与集合变量相同?
更新2:我认为收藏和实体可能会受到EF实体跟踪的影响,但我仍然无法理解为什么
用法:
ssp.ServiceAreas.ReplaceCollection(model.ServiceAreas);
这是我的扩展方法:
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);
}
答案 0 :(得分:4)
collection.Remove(collection.First(c => c.ID == item.ID));
您要删除正在迭代的集合。
答案 1 :(得分:1)
我创建了以下示例代码:
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);
}
}
这可以按照您的预期运行,没有错误。所以从本质上讲,这些线都没有引起问题。
如果您单独调用列表,会导致什么问题:
one.AddOrUpdate(one);
因此,从我所看到的,您必须使用与两个参数相同的集合来调用此扩展方法。
如果您是,那么Remove
或Add
都会改变集合并导致此异常。
答案 2 :(得分:0)
当有人接管它的元素时,或许EntityCollection
不喜欢?因此,当您添加到collection
时,项目将从items
中删除。
或者可能是items == collection
答案 3 :(得分:0)
可能是第一项始终是新项,因此默认情况下,ID设置为某个初始值。然后它将被添加到集合中,让EntityFramework生成一个新ID并将其分配给第一个添加的项目。
然后可能是EntityCollection认为它已经改变了,因为它使用ID来排序或在内部执行其他操作。因此,foreach操作(可能使用相同的列表)会抛出异常。这也是为什么Adam Houldsworth证明的测试用例没有给出问题的原因!
答案 4 :(得分:0)
EntityCollection<Customer> customers = new EntityCollection<Customer>();
Customer newCustomer = new Customer() {ID = 0};
customers.Add(newCustomer);
customers.AddOrUpdate(customers);