Entity Framework: более одного объекта имеют одинаковое значение первичного ключа - PullRequest
2 голосов
/ 03 июля 2019

Я пытаюсь сохранить указанный ниже объект в базе данных с кодом Entity Framework сначала, база данных была создана правильно, но когда вызывается SaveChanges();, то ниже исключения.

Не удалось сохранить или принять изменения, так как несколько сущностей типа «Условные исключения» имеют одно и то же значение первичного ключа. Убедитесь, что явно установленные значения первичного ключа являются уникальными. Убедитесь, что сгенерированные базой данных первичные ключи правильно настроены в базе данных и в модели Entity Framework. Используйте Entity Designer для конфигурации базы данных сначала / модели первой. Используйте свободно распространяемый API HasDatabaseGeneratedOption или DatabaseGeneratedAttribute для конфигурации Code First.

Может ли кто-нибудь взять меня в правильном направлении?

У меня есть этот 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");
                  });
    }
}

1 Ответ

0 голосов
/ 03 июля 2019

Проблема в вашей ForeignKey конфигурации в ConditionalOptions классе модели.Вы указали одно и то же свойство навигации на два внешних ключа, которые также являются вашим составным первичным ключом.

Поскольку первичный ключ 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" }));
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...