考虑以下错误:
InvalidOperationException: The instance of entity type 'OrderRegion' cannot be tracked because another instance with the key value '[Orderid: 10, RegionId: 1]' is already being tracked...
另外,请考虑以下类(为简洁起见略有删节):
public class Order
…
[Key]
public int Id { get; set; }
…
[Display(Name = "Regions")]
public ICollection<OrderRegion> OrderRegions { get; set; }
[Display(Name = "Stores")]
public ICollection<OrderStore> OrderStores { get; set; }
public class OrderRegion
{
//[Key]
public int OrderId { get; set; }
public Order Order { get; set; }
//[Key]
public int RegionId { get; set; }
public Region Region { get; set; }
}
public class OrderStore
{
//[Key]
public int OrderId { get; set; }
public Order Order { get; set; }
//[Key]
public int StoreId { get; set; }
public Store Store { get; set; }
}
与之相关的还有创建关联的上下文:
public class MyContext:DbContext
{
public MyContext(DbContextOptions<AzureOrdersContext> options) : base(options) { }
public DbSet<Order> Order { get; set; }
public DbSet<OrderRegion> OrderRegion { get; set; }
public DbSet<OrderStore> OrderStore { get; set; }
protected override void OnModelCreating(ModelBuilder modelBuilder)
{
…
modelBuilder.Entity<OrderRegion>()
.HasKey(nr => new { nr.OrderId, nr.RegionId });
modelBuilder.Entity<OrderRegion>()
.HasOne(nr => nr.Order)
.WithMany(n => n.OrderRegions)
.HasForeignKey(nr => nr.OrderId);
modelBuilder.Entity<OrderRegion>()
.HasOne(nr => nr.Region)
.WithMany(n => n.OrderRegions)
.HasForeignKey(nr => nr.RegionId);
modelBuilder.Entity<OrderStore>()
.HasKey(nr => new { nr.OrderId, nr.StoreId });
modelBuilder.Entity<OrderStore>()
.HasOne(nr => nr.Order)
.WithMany(n => n.OrderStores)
.HasForeignKey(nr => nr.OrderId);
modelBuilder.Entity<OrderStore>()
.HasOne(nr => nr.Store)
.WithMany(n => n.OrderStores)
.HasForeignKey(nr => nr.StoreId);
}
}
最后,我的“ Edit.cshtml.cs”中抛出了我的错误(被大量剪切):
public async Task<IActionResult> OnPostAsync(int? id, int[] AssignedRegions, int[] AssignedStores)
{
if (!ModelState.IsValid)
{
return Page();
}
var Ordertoupdate = await _context.Order
.Include(i => i.OrderRegions).ThenInclude(navigationPropertyPath: i => i.Region)
.Include(i => i.OrderStores).ThenInclude(navigationPropertyPath: i => i.Store)
.FirstOrDefaultAsync(m => m.Id == id);
...
if (await TryUpdateModelAsync<Web.Models.Order>(
Ordertoupdate,
"Order",
i => i.CreatedOn,
i => i.CreatedBy,
i => i.ModifiedBy, i => i.ExpirationDate,
...))
{
UpdateOrderRegions(_context, AssignedRegions, Ordertoupdate);
UpdateOrderStores(_context, AssignedStores, Ordertoupdate);
await _context.SaveChangesAsync();
return RedirectToPage("./Index");
}
UpdateOrderRegions(_context, AssignedRegions, Ordertoupdate);
UpdateOrderStores(_context, AssignedStores, Ordertoupdate);
PopulateAssignedRegions(_context, Ordertoupdate);
PopulateAssignedStores(_context, Ordertoupdate);
return Page();
}
该错误正在_context.SaveChangesAsync();上引发有任何想法吗?我确定我只是在做一些愚蠢的事情,没有看到简单的解决方法。
根据要求更新以包含UpdateOrderRegions:
public void UpdateOrderRegions (AzureOrdersContext _context, int[] SelectedRegions, Web.Models.Order OrderToUpdate)
{
if (SelectedRegions == null)
{
OrderToUpdate.OrderRegions = new List<OrderRegion>();
return;
}
var StoreRegionsToDelete= OrderToUpdate.OrderRegions.Where<OrderRegion>(nr => {
return !SelectedRegions.AsQueryable<Int32>().Contains<Int32>(nr.RegionId);
});
StoreRegionsToDelete.ToList().ForEach(r => { OrderToUpdate.OrderRegions.Remove(r); });
var StoreRegionsToAdd = SelectedRegions.AsQueryable<Int32>().Where<Int32>(regionId =>
!OrderToUpdate.OrderRegions.Any( nr=> nr.RegionId == regionId)
);
StoreRegionsToAdd.ToList().ForEach(regionId =>
OrderToUpdate.OrderRegions.Add(new OrderRegion
{
OrderId = OrderToUpdate.Id,
RegionId = regionId
}));
////This is where a different, more frustrating logical error lives but isn't related to my EF error
////Attempting to model after: https://github.com/aspnet/Docs/blob/master/aspnetcore/data/ef-rp/intro/samples/cu/Pages/Instructors/InstructorCoursesPageModel.cshtml.cs
var selectedRegionHS = new HashSet<string>(SelectedRegions);
var regionOrders = new HashSet<int>(OrderToUpdate.OrderRegions.Select(c => c.Order.Id));
foreach (var thisregion in _context.Region)
{
if (selectedRegionHS.Contains(thisregion.Id.ToString()))
{
if (!regionOrders.Contains(thisregion.Id))
{
OrderToUpdate.OrderRegions.Add(
new OrderRegion
{
OrderId = OrderToUpdate.Id,
RegionId = thisregion.Id
});
}
}
else
{
if (regionOrders.Contains(thisregion.Id))
{
OrderRegion RegionToRemove = OrderToUpdate.OrderRegions.SingleOrDefault(i => i.RegionId == thisregion.Id);
_context.Remove(RegionToRemove);
}
}
}
}
答案 0 :(得分:2)
当上下文中已经跟踪了一个项目,并且您显式尝试使用相同的键附加新对象时,会发生此问题。
考虑到错误在OrderRegion上,并且此类型具有OrderId / RegionId的复合键,我认为您很可能正在检索OrderRegion并使用相同的OrderId / RegionId组合附加新的OrderRegion。您可能需要检查OrderRegion键是否已经存在或清除订单区域并重新生成列表,以避免发生这种冲突。
我希望这可以为您指明正确的方向。随时提供处理OrderRegion更新的代码,我将尝试进一步提供帮助。