添加复杂项时 EF6 主键冲突

EF6 Primary Key Violation When adding Complex Item

我有一个 classes 的实体集,其中有一个食谱;该配方可以有多个成分(用外键处理),每个成分可以有一个组件。有几组 table 遵循与此类似的模式,其中有几层

当我添加一个配方时,其中包含一些最终导致相同组件的成分,我收到一条错误消息,指出将配方添加到数据库会导致组件发生主键冲突 table .有没有办法告诉实体,如果一个组件具有相同的主键值,它应该更新而不是插入?我知道您可以使用 context.Recipes.AddOrUpdate(recipe) 在顶层执行此操作,但我如何才能在树结构中的每个子级别实现它?

以下是我已有的实体 classes 的一些总结示例:

public partial class Recipe
{
    public int Id { get; set; }
    public virtual ICollection<Ingredient> Ingredients { get; set; }
}

public partial class Ingredient
{
    public int Id {get;set;}
    public int ComponentId { get; set; }
    public virtual Component Component { get; set; }
    public virtual ICollection<Recipe> Recipes { get; set; }
}

public partial class Component
{
    [DatabaseGenerated(DatabaseGeneratedOption.None)]
    public int Id { get; set; }
    public string Description { get; set; }
    public virtual ICollection<Ingredient> Ingredients { get; set; }
}

//在:DbContext class中,有这个:

    modelBuilder.Entity<Ingredient>()
        .HasMany(e => e.Recipes)
        .WithMany(e => e.Ingredients)
        .Map(m => m.ToTable("Recipe_Ingredient_Link").MapLeftKey("IngredientId").MapRightKey("RecipeId"));

我收到此错误消息是因为具有相同 Id 的两个组件具有不同的 Ingredients ICollections 与之关联,导致 Entity 将它们视为不同的对象吗?如果是这样,我该如何解决这个问题?如果不是,是什么问题?

我从现有数据库生成 classes,除了关闭延迟加载外,没有更改它为我创建的代码。

我认为您的问题在于,在从 JSON 到 C# 对象的转换中,您为 JSON 中的每个组件获得了一个单独的对象。这意味着即使两个组件具有相同的 ID,它也是两个不同的对象,就像您也描述的那样。如图所示:

Recipe #1
|
|-- Ingr. #1
|   |-- Comp. #1
|
|-- Ingr. #2
|   |-- Comp. #2
|
|-- Ingr. #3
    |-- Comp. #1  // Same ID as the one for Ingr. 1, but it's a separate C# object

当您尝试添加对象层次结构(通过仅添加 top-level Recipe)时,Entity Framework 会将每个 C# 对象视为一个单独的实体。因此,即使两个对象共享相同的 ID,也没有逻辑告诉 EF 如何处理它。 IE。如果其他属性(除了 ID)不同,它应该如何表现?

所以我认为您需要做的是确保没有两个对象具有冲突的 ID。您必须遍历对象并确保如果两个组件具有相同的 ID,则需要删除其中一个组件并将 Ingredients link 指向同一个 Component 对象,如图所示:

Recipe #1
|
|-- Ingr. #1
|   |----------------|
|                    |
|-- Ingr. #2         |
|   |-- Comp. #2     |-- Comp. #1 // Now they point to the same C# object
|                    |
|-- Ingr. #3         |
    |----------------|

我会让你考虑如何编写代码。