.net core EF核心删除复合密钥实体

.net core EF核心删除复合密钥实体,.net-core,entity-framework-core,composite-primary-key,icomparable,.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 ICompa

下面我提取了代码的相关部分。问题是何时调用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)
保存更改时数据库中发生异常。
System.InvalidOperationException:无法比较数组中的两个元素。-->System.ArgumentException:至少一个对象必须实现IComparable。
在System.Collections.Comparer.Compare处(对象a、对象b)
在lambda_方法(闭包、对象、对象)
位于Microsoft.EntityFrameworkCore.Update.Internal.ModificationCommandComparer.Compare(ModificationCommand x,ModificationCommand y)
位于System.Collections.Generic.ArraySortHelper`1.InsertionSort(T[]键,Int32 lo,Int32 hi,IComparer`1比较器)
位于System.Collections.Generic.ArraySortHelper`1.IntrospectiveSort(T[]键,左Int32,左Int32长度,IComparer`1比较器)
位于System.Collections.Generic.ArraySortHelper`1.Sort(T[]键,Int32索引,Int32长度,IComparer`1比较器)
---内部异常堆栈跟踪的结束---
位于System.Collections.Generic.ArraySortHelper`1.Sort(T[]键,Int32索引,Int32长度,IComparer`1比较器)
位于System.Collections.Generic.List`1.Sort(Int32索引、Int32计数、IComparer`1比较器)
在Microsoft.EntityFrameworkCore.Update.Internal.CommandBatchPreparer.d_u6.MoveNext()中
位于Microsoft.EntityFrameworkCore.Update.Internal.BatchExecutor.Execute(元组`2参数)
位于Microsoft.EntityFrameworkCore.ChangeTracking.Internal.StateManager.SaveChanges(IReadOnlyList`1 entriesToSave)
位于Microsoft.EntityFrameworkCore.ChangeTracking.Internal.StateManager.SaveChanges(布尔接受更改成功)
在Microsoft.EntityFrameworkCore.DbContext.SaveChanges(布尔接受更改成功)
现在我认为问题出在我用的钥匙上。我为每个商店都有一个唯一的商店ID,并且为每个商店中的每个商品都有一个唯一的商品ID。可以使用StoreId+ItemId获得项目的全局唯一ID

我完全不确定为什么这里会调用任何类型的SaveChanges。即使密钥不是复合的,只是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);
}
//这是实体类。
公共类项目
{
[必需]
[最大长度(最大长度)]
公共字节[]ItemId{get;set;}
[必需]
[最大长度(最大长度)]
公共字节[]存储ID{get;set;}
}
//这就是我如何在上下文中设置它的密钥的方法——正如我在迁移文件中看到的,密钥是按预期创建的。
模型创建时受保护的覆盖无效(ModelBuilder ModelBuilder)
{
基于模型创建(modelBuilder);
modelBuilder.Entity().HasKey(i=>new{i.ItemId,i.StoreId});
modelBuilder.Entity().HasIndex(i=>new{i.ItemId,i.StoreId}).IsUnique();
}
//这就是问题所在
公共空间X()
{
使用(UnitOfWork UnitOfWork=新建UnitOfWork())
{
List items=unitOfWork.ItemRepository.Get().ToList();
foreach(项目中的项目)
unitOfWork.ItemRepository.Delete(项目);
unitOfWork.SaveChanges();
}
}
//这就是如何在通用存储库(即ItemRepository)中实现删除。
公共虚拟无效删除(TEntity entityToDelete)
{
if(context.Entry(entityToDelete.State==EntityState.Detached)
数据库集连接(entityToDelete);
dbSet.Remove(entityToDelete);
}
更新:当我试图向现有类添加一个简单的int作为主键时,代码开始工作


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

数据库中ItemId和StoreId的数据类型是什么?它是BLOB NOT NULL(在迁移文件中是
table.Column(maxLength:32,nullable:false)
),我忘了提到我正在使用SQLite。还有一个约束是主键(“ItemId”、“StoreId”)EF(通常和.net)不能比较两个字节[]。唯一实现IComparable或基本值的对象,如int或byte,。。。可以比较,所以尝试将项设置为IComparable或使用其他类型作为主键我同意Silvinus,为什么要将guid、int或varchar用于pk?我也同意Silvinus,但我没有找到如何使项实现IComparable,以便与EF一起工作。当我在Item类上实现IComparable时,它完全没有什么区别,所以我想这个问题是关于如何使它工作的。