Entity Framework (сначала код) создает ненужные дублированные внешние ключи - PullRequest
0 голосов
/ 26 февраля 2019

У меня есть что-то вроде следующего типичного кода:

public class Parent 
{
    public int Id { get; set; }
    public ICollection<Child> Children { get; set; }
}

public class Child 
{
    public int Id { get; set; }
    [Required]
    public Parent Parent { get; set; }
}

И Entity Framework создает что-то вроде:

create table Children
(
    Id int identity constraint [PK_dbo.Children] primary key,
    Parent_Id int
        constraint FK_dbo.Children_dbo.Parent_Parent_Id
            references Parents,
}

Затем я добавляю каскадное удаление с помощью:

protected override void OnModelCreating(DbModelBuilder modelBuilder)
{
    modelBuilder.Entity<Parent>()
    .HasMany(x => x.Children)
    .WithRequired()
    //.HasForeignKey(x => x.Parent) // my wrong try 
    .WillCascadeOnDelete(true);
}

И EF создает что-то вроде:

create table Children
(
    Id int identity constraint [PK_dbo.Children] primary key,
    Parent_Id int
        constraint FK_dbo.Children_dbo.Parent_Parent_Id
            references Parents,
    Parent_Id1 int
        constraint FK_dbo.Children_dbo.Parent_Parent_Id1
            references Parents,
    ...
}

т.е. EF создает дубликаты FK: Parent_Id и Parent_Id1.Почему?

Я пробовал разные варианты, но не смог избавиться от ненужных дубликатов.

Пожалуйста, кто-нибудь может помочь решить эту проблему?

Обновление:

Майкл, большое спасибо за ваш ответ.Я читал эту статью и пробовал разные варианты, но, к сожалению, безуспешно.Атрибут [InverseProperty("Parent")] также не помог.

В моем случае Parent.Children - это ApplicationUser.YmSitesChild.Parent - это YmSite.User.

Только сейчас я даже пробую следующий прямой скрипт T-SQL:

ALTER TABLE DB_9B2F.dbo.YmSites DROP CONSTRAINT [FK_dbo.YmSites_dbo.AspNetUsers_User_Id]
ALTER TABLE DB_9B2F.dbo.YmSites
ADD CONSTRAINT [FK_dbo.YmSites_dbo.AspNetUsers_User_Id]
FOREIGN KEY (User_Id) REFERENCES AspNetUsers (Id) ON DELETE CASCADE

Но я получаю ошибку:

Это свойство не поддерживается: ApplicationName.

Очень странно.

1 Ответ

0 голосов
/ 26 февраля 2019

Проблема

  1. EF уже создала связь, и было включено каскадное удаление
  2. Затем вы снова определили ее с помощью DbModelBuilder

Короче я думал, что у тебя 2 отношения.поэтому вам не нужно ничего делать, просто удалите код DbModelBuilder

Однако, если вам нужно было что-то сделать с конструктором моделей, например отключить каскадное удаление, или вы просто хотите сделать это для избыточности(кто знает почему).Один из способов достижения этого - явное указание EF , что у вас есть связь (один) между Parent и Child с использованием аннотации данных InverseProperty

public class Parent 
{
  public int Id { get; set; }

  [InverseProperty("Parent")]
  public ICollection<Child> Children { get; set; }
}

Примечание : обычно обратным свойством является объявление нескольких отношений, однако в этом случае это работает, потому что вы даете понять, что вам просто нужны эти отношения


Чтобы получить полный ответ, я попытался найти чье-то слово для этого ниже.

Каскадное удаление в отношениях один-ко-многим

Примечание : EF автоматически удаляет связанные записи в средней таблице для объектов отношения "многие ко многим", если удаляется одна или другая сущность.

Таким образом, EF включает эффект каскадного удаления с помощьюпо умолчанию для всех сущностей.

...