如果有2个外键(代码优先),则EF Core自引用不起作用



如果我(首先在代码中)定义了一个导航属性,它就可以工作(创建外键),但如果我定义了2,它就不工作了
如何为自己创建2个外键应该根据惯例的文档来创建它们。

例如,这项工作(创建外键):

public class DbPart 
{
[Key]
[Required]
[DatabaseGenerated(DatabaseGeneratedOption.Identity)]
public int Id { get; set; }
[ForeignKey("Source")]
public int? SourceId { get; set; }
public DbPart Source { get; set; }
[InverseProperty("Source")]
public List<DbPart> SourceParts { get; set; }
}

这个也是:

public class DbPart 
{
[Key]
[Required]
[DatabaseGenerated(DatabaseGeneratedOption.Identity)]
public int Id { get; set; }
[ForeignKey("SourceFake")]
public int? SourceFakeId { get; set; }
public DbPart SourceFake { get; set; }
[InverseProperty("SourceFake")]
public List<DbPart> SourceFakeParts { get; set; }
}

但不是这个:

public class DbPart 
{
[Key]
[Required]
[DatabaseGenerated(DatabaseGeneratedOption.Identity)]
public int Id { get; set; }
[ForeignKey("Source")]
public int? SourceId { get; set; }
public DbPart Source { get; set; }

[ForeignKey("SourceFake")]
public int? SourceFakeId { get; set; }
public DbPart SourceFake { get; set; }
[InverseProperty("SourceFake")]
public List<DbPart> SourceFakeParts { get; set; }
[InverseProperty("Source")]
public List<DbPart> SourceParts { get; set; }
}

我还有另一个例子,我在数据库中写树结构,但我只写ParentId,还写RootId。同样,当将2个属性引用到self(ParentId、RootId)时,不会创建外键。

已编辑:
由于此错误,它无法工作。简单的解决方案是从Id属性中删除[Key],或者在Steve Greene的回答中使用流畅的解决方案。也可以在此处查看。

我更喜欢这种东西的流畅代码:

modelBuilder.Entity<DbPart>()
.HasOne(p => p.Source)
.WithMany(p => p.SourceParts)
.HasForeignKey(p => p.SourceId);
modelBuilder.Entity<DbPart>()
.HasOne(p => p.SourceFake)
.WithMany(p => p.SourceFakeParts)
.HasForeignKey(p => p.SourceFakeId);

但如果你想要注释,试试这个:

public class DbPart 
{
public int Id { get; set; }   // Key & Indentity by convention
public int? SourceId { get; set; }  // FK by convention
[InverseProperty("SourceParts")]
public DbPart Source { get; set; }
public int? SourceFakeId { get; set; } // FK by convention
[InverseProperty("SourceFakeParts")]
public DbPart SourceFake { get; set; }
[InverseProperty("SourceFake")]
public List<DbPart> SourceFakeParts { get; set; }
[InverseProperty("Source")]
public List<DbPart> SourceParts { get; set; }
}

最新更新