【问题标题】:EF Change Tracker: Collection was modified; enumeration operation may not executeEF Change Tracker:集合已修改;枚举操作可能无法执行
【发布时间】:2013-10-27 07:33:34
【问题描述】:

我在遍历集合时遇到错误。我不会在任何时候更改列表,但它给了我以下“集合已修改;枚举操作可能无法执行。以下代码显示了我拥有此 Parallel.Foreach 的方法。

public void DownloadImages()
        {
            IList<Vehicle> vehicles = _repository.Retrieve().ToList();
            Parallel.ForEach(vehicles, vehicle =>
            {
                IList<VehiclePhoto> vehiclePhotos =
                    vehicle.VehiclePhotos.Where(x => x.ImageStatus == ImageStatus.Inactive).ToList();
                if (vehiclePhotos.Count > 0)
                {
                    Parallel.ForEach(vehiclePhotos, photo =>
                    {
                        using (var client = new WebClient())
                        {
                            try
                            {
                                string fileName = Guid.NewGuid() + ".png";
                                string filePath = _imagePath + "\\" + fileName;
                                client.DownloadFile(photo.ImageUrl, filePath);
                                photo.FileName = fileName;
                                photo.ImageStatus = ImageStatus.Active;
                            }
                            catch (Exception)
                            {
                            }
                        }
                    });

                    _repository.Save(vehicle);
                }
            });
        }

这发生在调用 _repository.Save(vehicle) 时。以下代码将显示保存更改方法。 base.SaveChanges();是引发错误的地方。

public override int SaveChanges()
        {
            DateTime nowAuditDate = DateTime.Now;
            IEnumerable<System.Data.Entity.Infrastructure.DbEntityEntry<DomainEntity>> changeSet = ChangeTracker.Entries<DomainEntity>();
            if (changeSet != null)
            {
                foreach (System.Data.Entity.Infrastructure.DbEntityEntry<DomainEntity> entry in changeSet)
                {
                    switch (entry.State)
                    {
                        case EntityState.Added:
                            entry.Entity.Created = nowAuditDate;
                            entry.Entity.Modified = nowAuditDate;
                            break;
                        case EntityState.Modified:
                            entry.Entity.Modified = nowAuditDate;
                            break;
                    }
                }
            }

            return base.SaveChanges();
        }

对此有什么想法吗?

已编辑: 我试图修复上述错误并在 DownloadImages 方法中更改了几行代码。这些变化如下:

代替

IList<Vehicle> vehicles = _repository.Retrieve().ToList(); 

我用过 var

var vehicles = _repository.Retrieve().AsParallel(); 

代替

IList<VehiclePhoto> vehiclePhotos =
                        vehicle.VehiclePhotos.Where(x => x.ImageStatus == ImageStatus.Inactive).ToList();

我用过 var

var  vehiclePhotos =
                            vehicle.VehiclePhotos.Where(x => x.ImageStatus == ImageStatus.Inactive).AsParallel();

当我再次尝试运行代码时。它给了我一个不同的错误:错误如下:

在标题中说

System.Data.Entity.Infrastructure.DbUpdateException

但是在innerException中

System.Data.Entity.Core.UpdateException

当分配给命令的连接处于挂起的本地事务中时,ExecuteNonQuery 要求该命令具有事务。该命令的 Transaction 属性尚未初始化。

【问题讨论】:

    标签: c# asp.net-mvc entity-framework


    【解决方案1】:

    发生这种情况是因为您正在迭代 vehicles 并且循环内的代码正在更改枚举 vehicles 的元素。另外,循环遍历vehiclePhotos 并更改其中的元素。

    我通常使用显式的for 循环来解决这个问题,即:

    for(var i = 0; i < vehicles.Count; i++)
    {
        var vehicle = vehicles.ElementAt(i);
    
        // process vehicle
    }
    

    但是,如果您需要使用Parallel.ForEach,您可以尝试创建一个长度为vehicles.Count 的整数数组,对其进行迭代并将其用作vehicles 的索引。

    【讨论】:

    • 最近我们在尝试改进检查我们的 CRM 帐户操作所需的文件时遇到了同样的问题(我们所有的帐户每晚运行一次),不幸的是没有运气将我们的列表枚举到数组(accounts.ToArray( )) 并在 Parallel.For 中通过它。有什么想法吗?
    • account.ToArray() 只会对与初始集合中完全相同的对象进行引用数组。它不会复制每个对象。因此,如果数组的元素发生变化,您将遇到同样的问题。尝试创建索引数组并遍历这些索引,使用索引访问集合的元素,即accounts[i].DoSomething()
    猜你喜欢
    • 1970-01-01
    • 2015-06-17
    • 2020-02-07
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2022-06-17
    • 1970-01-01
    • 2011-10-05
    相关资源
    最近更新 更多