Экземпляр ASP.Net Core EF MM не может быть отслежен - PullRequest
0 голосов
/ 05 февраля 2019

Рассмотрим следующую ошибку:

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);
                }
            }
        }
    }

1 Ответ

0 голосов
/ 05 февраля 2019

Эта проблема возникает, когда контекст уже отслеживает элемент, и вы явно пытаетесь присоединить новый объект с тем же ключом.

Учитывая, что ошибка в OrderRegion и этот тип имеет составной ключ OrderId / RegionId, я думаю, что вы, вероятно, извлекаете OrderRegion и присоединяете новый OrderRegion с той же комбинацией OrderId / RegionId.Возможно, вам придется проверить, существует ли ключ OrderRegion, или очистить регионы заказа и пересоздать список, чтобы избежать этого конфликта.

Надеюсь, это направит вас в правильном направлении.Не стесняйтесь указывать код для обработки обновлений OrderRegion, и я постараюсь помочь вам.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...