EF核心删除复合键实体

时间:2016-12-12 17:22:09

标签: .net-core entity-framework-core composite-primary-key icomparable

下面我提取了相关的代码部分。问题是调用X()时。我得到以下异常:

An exception occurred in the database while saving changes.
System.InvalidOperationException: Failed to compare two elements in the array. ---> System.ArgumentException: At least one object must implement IComparable.
  at System.Collections.Comparer.Compare(Object a, Object b)
  at lambda_method(Closure , Object , Object )
  at Microsoft.EntityFrameworkCore.Update.Internal.ModificationCommandComparer.Compare(ModificationCommand x, ModificationCommand y)
  at System.Collections.Generic.ArraySortHelper`1.InsertionSort(T[] keys, Int32 lo, Int32 hi, IComparer`1 comparer)
  at System.Collections.Generic.ArraySortHelper`1.IntrospectiveSort(T[] keys, Int32 left, Int32 length, IComparer`1 comparer)
  at System.Collections.Generic.ArraySortHelper`1.Sort(T[] keys, Int32 index, Int32 length, IComparer`1 comparer)
 --- End of inner exception stack trace ---
  at System.Collections.Generic.ArraySortHelper`1.Sort(T[] keys, Int32 index, Int32 length, IComparer`1 comparer)
  at System.Collections.Generic.List`1.Sort(Int32 index, Int32 count, IComparer`1 comparer)
  at Microsoft.EntityFrameworkCore.Update.Internal.CommandBatchPreparer.<BatchCommands>d__6.MoveNext()
  at Microsoft.EntityFrameworkCore.Update.Internal.BatchExecutor.Execute(Tuple`2 parameters)
  at Microsoft.EntityFrameworkCore.ChangeTracking.Internal.StateManager.SaveChanges(IReadOnlyList`1 entriesToSave)
  at Microsoft.EntityFrameworkCore.ChangeTracking.Internal.StateManager.SaveChanges(Boolean acceptAllChangesOnSuccess)
  at Microsoft.EntityFrameworkCore.DbContext.SaveChanges(Boolean acceptAllChangesOnSuccess)

目前我认为问题是由于我在那里使用的密钥。我为每个商店都有一个唯一的商店ID,每个商店的每件商品都有一个唯一的商品ID。可以使用StoreId + ItemId获取项目的全局唯一ID。

我完全不确定为什么在SaveChanges上调用任何类型的Sort。即使密钥不是复合密钥而只是ItemId,也会出现问题。

我很乐意获得任何线索。

代码段:

// This is the entity class.
public class Item
{
  [Required]
  [MaxLength(MaxIdLength)]
  public byte[] ItemId { get; set; }

  [Required]
  [MaxLength(MaxIdLength)]
  public byte[] StoreId { get; set; }
}

// This is how I setup its Key in context - as I can see in the migration file, the key is created as expected.
protected override void OnModelCreating(ModelBuilder modelBuilder)
{
  base.OnModelCreating(modelBuilder);
  modelBuilder.Entity<Item>().HasKey(i => new { i.ItemId, i.StoreId });
  modelBuilder.Entity<Item>().HasIndex(i => new { i.ItemId, i.StoreId }).IsUnique();
}

// This is the problem
public void X()
{
  using (UnitOfWork unitOfWork = new UnitOfWork())
  {
    List<Item> items = unitOfWork.ItemRepository.Get().ToList();

    foreach (Item item in items)
      unitOfWork.ItemRepository.Delete(item);

    unitOfWork.SaveChanges();
  }
}

// This is how Delete is implemented in the generic repository (i.e. ItemRepository).
public virtual void Delete(TEntity entityToDelete)
{
  if (context.Entry(entityToDelete).State == EntityState.Detached)
    dbSet.Attach(entityToDelete);

  dbSet.Remove(entityToDelete);
}

UPDATE:当我尝试添加一个简单的int作为现有类的主键时,代码开始起作用。

更新2:即使密钥只是ItemId,也会出现问题。可能存在一个问题,即它不是自动生成的密钥类型。

0 个答案:

没有答案