簡體   English   中英

實體框架:多個實體具有相同的主鍵值

[英]Entity Framework : more than one entity have the same primary key value

我正在嘗試使用Entity Framework代碼優先將下面的對象保存到數據庫,數據庫已正確創建,但是當SaveChanges();SaveChanges(); 被稱為異常之下發出聲響。

保存或接受更改失敗,因為多個“ ConditionalOptions”類型的實體具有相同的主鍵值。 確保顯式設置的主鍵值是唯一的。 確保在數據庫和實體框架模型中正確配置了數據庫生成的主鍵。 將實體設計器用於數據庫優先/模型優先配置。 使用“ HasDatabaseGeneratedOption”流利的API或“ DatabaseGeneratedAttribute”進行代碼優先配置。

誰能帶我去正確的方向?

我有這個JSON:

{
    "components": [
        {
            "label": "Text Field",
            "key": "1",
            "conditional": {
                "show": "",
                "when": "",
                "json": ""
            }
        },
        {
            "label": "Columns",
            "columns": [
                {
                "ParentComponentKey":"4",
                    "components": [
                        {
                            "label": "Text Field",
                            "key": "5",
                            "conditional": {
                                "show": "",
                                "when": "",
                                "json": ""
                            }
                        }
                    ],
                    "Id":"1"
                }
            ],
            "key": "4",
            "conditional": {
                "show": "",
                "when": "",
                "json": ""
            }
        },
        {
            "type": "button",
            "label": "Submit",
            "key": "7",
            "disableOnInvalid": true,
            "theme": "primary",
            "input": true,
            "tableView": true
        }
    ]
}

我創建了以下模型類以將數據映射到對象中:

public class Form
{
    public Form()
    {
        this.Components = new HashSet<ComponentOptions>();
    }

    [Key]
    public int Id { get; set; }
    public string title { get; set; }
    public virtual ICollection<ComponentOptions> Components { get; set;}
}

public class ComponentOptions
{
    [Key, Column(Order = 0)]
    public int FormId { get; set; }

    [Key, Column(Order = 1)]
    public int Key { get; set; }

    public string label { get; set; }

    public virtual ConditionalOptions conditional { get; set; }
    public virtual ICollection<ColumnOptions> columns { get; set; }

    [ForeignKey("FormId")]
    public virtual Form Form { get; set; }
}

public class ConditionalOptions
{
    [Key, ForeignKey("ComponentOptions"), Column(Order = 0)]
    public Int64 FormId { get; set; }

    [Key, ForeignKey("ComponentOptions"), Column(Order = 1)]
    public int Key { get; set; }
    public string show { get; set; }
    public string when { get; set; }
    public string eq { get; set; }

    public virtual ComponentOptions ComponentOptions { get; set; }
}

public class ColumnOptions
{
    //[ForeignKey("FormId,Key")]
    //public virtual ComponentOptions ComponentOption { get; set; }
    public ColumnOptions()
    {
        this.components = new HashSet<ComponentOptions>();
    }

    [Key, Column(Order = 0)]
    public Int64 FormId { get; set; }

    [Key, Column(Order = 1)]
    public int ParentComponentKey { get; set; } 

    [Key, Column(Order = 2)]
    public int Id { get; set; }

    public string Key { get; set; }
    public int width { get; set; }
    public int offset { get; set; }
    public int push { get; set; }
    public int pull { get; set; }

    public virtual ICollection<ComponentOptions> components { get; set; }

    [ForeignKey("FormId")]
    public virtual Form Form { get; set; }
}

public class EntitesContext : DbContext
{
    public EntitesContext() : base("name=FBEntities")
    {
        Database.SetInitializer<EntitesContext>(new System.Data.Entity.CreateDatabaseIfNotExists<EntitesContext>());
    }

    public IDbSet<Form> FormDataSet { get; set; }
    public IDbSet<ColumnOptions> ColumnOptionsDataSet { get; set; }
    public IDbSet<ComponentOptions> ComponentOptionsDataSet { get; set; }
    public IDbSet<ConditionalOptions> ConditionalOptionsDataSet { get; set;}

    protected override void OnModelCreating(DbModelBuilder modelBuilder)
    {
        modelBuilder.Conventions.Remove<OneToManyCascadeDeleteConvention>();
        modelBuilder.Conventions.Remove<ManyToManyCascadeDeleteConvention>();

        modelBuilder.Entity<ComponentOptions>()
                  .HasMany(s => s.columns)
                  .WithMany(c => c.components)
                  .Map(cs =>
                  {
                      cs.MapLeftKey("ComponentFormId", "ComponentKey");
                      cs.MapRightKey("ColumnFormId", "ColumnComponentKey", "ColumnId");
                      cs.ToTable("ComponentColumn");
                  });
    }
}

問題出在ConditionalOptions模型類中的ForeignKey配置中。 您已經將相同的導航屬性指向了兩個外鍵,這兩個外鍵也是您的復合主鍵。

由於ComponentOptions的主鍵是組合鍵,因此您的ConditionalOptions配置應該有些技巧,如下所述,以保持它們之間one-to-one關系。

public class ConditionalOptions
{
    [Key]
    public Int64 ConditionalOptionsId { get; set; }

    public string show { get; set; }
    public string when { get; set; }
    public string eq { get; set; }

    public virtual ComponentOptions ComponentOptions { get; set; }
}

然后使用Fluent API,如下所示:

modelBuilder.Entity<ConditionalOptions>()
            .HasRequired(co => co.ComponentOptions)
            .WithOptional(c => c.conditional)
            .Map(co => co.MapKey(new []{ "FormId", "Key" }));

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM