实体框架(代码优先)创建不必要的重复外键

时间:2019-02-26 01:30:38

标签: c# entity-framework ef-code-first

我有类似以下的典型代码:

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; }
}

实体框架创建类似以下内容的

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_IdParent_Id1。为什么?

我尝试了不同的变体,但无法摆脱不必要的重复。

请,任何人都可以帮助解决此问题吗?

更新

迈克尔,非常感谢您的答复。我阅读了这篇文章并尝试了不同的变体,但不幸的是没有成功。 [InverseProperty("Parent")]属性也无济于事。

在我的情况下,Parent.ChildrenApplicationUser.YmSites。而Child.ParentYmSite.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 :(得分:0)

问题

  1. EF已经创建了关系,并且已启用级联删除
  2. 然后,您再次使用DbModelBuilder
  3. 对其进行了定义。

简而言之,我认为您有2个关系。因此,您无需执行任何操作,只需删除DbModelBuilder代码

但是,如果您需要对模型构建器进行某些操作(例如关闭层叠删除),或者只是希望在那里进行冗余(谁知道为什么)。实现此目标的一种方法是使用 InverseProperty 数据批注明确告诉 EF 您在ParentChild之间有一个(一个)关系

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

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

注意 :通常,逆属性是声明多个关系,但是在这种情况下,它是可行的,因为您知道它只是想要那个关系


要获得完整答案,我尝试在下面找到其他人的用语。

Cascade Delete in One-to-Many Relationships

  

注意:EF会自动删除中间表中的相关记录   多对多关系实体(如果一个或另一个实体是   删除。

     

因此,默认情况下,EF为所有   实体。