Рассмотрим следующую ошибку:
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);
}
}
}
}