EF 更改跟踪器:集合已修改;枚举操作可能无法执行
本文关键字:操作 枚举 执行 修改 跟踪 集合 EF | 更新日期: 2023-09-27 18:36:05
我在循环访问集合时收到错误。我不会在任何时候更改列表,但它给了我以下"集合已修改;枚举操作可能无法执行。下面的代码显示了我有这个 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时。保存(车辆)被调用。以下代码将显示保存更改方法。基础。保存更改();是引发错误的地方。
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 vehicles = _repository.Retrieve().AsParallel();
而不是
IList<VehiclePhoto> vehiclePhotos =
vehicle.VehiclePhotos.Where(x => x.ImageStatus == ImageStatus.Inactive).ToList();
我使用了变量
var vehiclePhotos =
vehicle.VehiclePhotos.Where(x => x.ImageStatus == ImageStatus.Inactive).AsParallel();
当我尝试再次运行代码时。它给了我一个不同的错误:错误如下:
在标题中它说
System.Data.Entity.Infrastructure.DbUpdateException
但在内部异常
System.Data.Entity.Core.UpdateException
当分配给命令的连接位于挂起的本地事务中时,ExecuteNonQuery 要求命令具有事务。 命令的事务属性尚未初始化。
发生这种情况是因为您正在迭代vehicles
并且循环中的代码正在更改枚举vehicles
的元素。此外,循环vehiclePhotos
并更改其元素。
我通常通过使用显式for
循环来解决此问题,即:
for(var i = 0; i < vehicles.Count; i++)
{
var vehicle = vehicles.ElementAt(i);
// process vehicle
}
但是,如果您需要使用 Parallel.ForEach
,您可以尝试创建一个长度为 vehicles.Count
的整数数组,迭代该数组并将其用作vehicles
的索引。