使用 Entity Framework Core 5 的自引用表

Sve*_*ven 4 entity-framework-core .net-core

我的应用程序中有一个自引用实体。与其他包类型具有依赖关系(作为列表)的包类型。我正在尝试使用模型生成器设计所需的中间表。不幸的是我无法正确填写密钥。

System.InvalidOperationException:“无法跟踪“PackageDependency(Dictionary <string,object>)”类型的实体,因为其主键属性“DependencyId”为空。”

    public class PackageType
    {
        [Key]
        public String Tag { get; set; }

        public virtual List<PackageType> Dependencies { get; set; } = new List<PackageType>();
    }

Run Code Online (Sandbox Code Playgroud)

数据库上下文:

 protected override void OnModelCreating(ModelBuilder modelBuilder)
        {
            modelBuilder.Entity<PackageType>()
                .HasMany(p => p.Dependencies)
                .WithMany(p => p.Dependencies)
                .UsingEntity<Dictionary<string, object>>(
                    "PackageDependency",
                    j => j
                        .HasOne<PackageType>()
                        .WithMany()
                        .HasForeignKey("PackageId")
                        .HasConstraintName("FK_PackageDependency_PackageId")
                        .OnDelete(DeleteBehavior.Cascade),
                    j => j
                        .HasOne<PackageType>()
                        .WithMany()
                        .HasForeignKey("DependencyId")
                        .HasConstraintName("FK_PackageDependency_DependencyId")
                        .OnDelete(DeleteBehavior.ClientCascade),
                    e => e.HasKey("PackageId", "DependencyId"));
        }
Run Code Online (Sandbox Code Playgroud)

有人给我提示吗?

多谢!

Iva*_*oev 5

我很惊讶 EF Core 甚至允许这样做

.HasMany(p => p.Dependencies)
.WithMany(p => p.Dependencies)
Run Code Online (Sandbox Code Playgroud)

(对关系的双方使用同一个集合)而不报告错误。

多对多需要 2 个集合导航属性 - 关系的每一方各一个。因此,即使这是自引用关系,它仍然需要 2 个单独的集合导航属性绑定到相应的连接实体 FK。例如

public virtual List<PackageType> ChildDependencies { get; set; } = new List<PackageType>();
public virtual List<PackageType> ParentDependencies { get; set; } = new List<PackageType>();
Run Code Online (Sandbox Code Playgroud)

.HasMany(p => p.ChildDependencies) // -> j.PackageId
.WithMany(p => p.ParentDependencies) // -> j.DependencyId
Run Code Online (Sandbox Code Playgroud)