C# ASP.NET MVC 5实体框架6自引用一对多关系

C# ASP.NET MVC 5实体框架6自引用一对多关系,c#,asp.net-mvc,entity-framework,C#,Asp.net Mvc,Entity Framework,我有一个模型包,我想在其上添加一个集合属性依赖项,其中依赖项只是另一个包(想想NuGet): 我将此模式更改理解为对单个现有包的引用。要创建多个包引用,将需要额外的行,其中包含所有重复数据(除了包ID)。这对我来说似乎不太正确,或者可能只是关系数据库的一个限制 难道我们不能在一列中存储一个packageID数组,或者使用其他不生成重复数据的机制吗?您的模式不能正确地表示您试图解决的问题。由于多个包可能依赖于同一个包(即,一切都取决于EF),因此您需要创建多对多关系。EF中的m:m支持有些有限,因

我有一个模型
,我想在其上添加一个集合属性
依赖项
,其中依赖项只是另一个包(想想NuGet):

我将此模式更改理解为对单个现有包的引用。要创建多个包引用,将需要额外的行,其中包含所有重复数据(除了
包ID
)。这对我来说似乎不太正确,或者可能只是关系数据库的一个限制


难道我们不能在一列中存储一个packageID数组,或者使用其他不生成重复数据的机制吗?

您的模式不能正确地表示您试图解决的问题。由于多个包可能依赖于同一个包(即,一切都取决于EF),因此您需要创建多对多关系。EF中的m:m支持有些有限,因此最简单的方法是为依赖项创建一个新实体(=表):您需要两个字段(=列)-一个用于依赖项的父字段,一个用于依赖项的子字段。

EF无法为您解析映射。在这种情况下,您将需要类似于以下内容的自定义映射:

protected override void OnModelCreating(DbModelBuilder modelBuilder)
    {
        modelBuilder.Entity<Package>()
            .HasMany(p => p.Dependencies)
            .WithMany()
            .Map(m =>
            {
                m.MapLeftKey("Package_ID");
                m.MapRightKey("ID");
                m.ToTable("PackageDependency");
            });
}
模型创建时受保护的覆盖无效(DbModelBuilder modelBuilder)
{
modelBuilder.Entity()
.HasMany(p=>p.Dependencies)
.有很多
.Map(m=>
{
m、 MapLeftKey(“包号”);
m、 MapRightKey(“ID”);
m、 ToTable(“PackageDependency”);
});
}

这将指示EF生成DDL代码以创建一个联合表来存储包之间所有可能的关系/依赖关系。

您不需要创建额外的实体,但必须为此场景创建一个自定义映射。@E-Bat您能详细说明一下吗?好的,我发布了我建议的解决方案。好主意!我将尝试并报告:)我将如何修改我的迁移以支持此操作?如果您已将迁移应用于数据库,则需要回滚并使用此映射创建新迁移。我已将此方法添加到我的
DbContext
类中,但出现错误“名称“依赖项”在当前上下文中不存在”。我需要添加一个
DbSet Dependencies
来建模吗?哦,不,对不起,应该是p.Dependencies。我将更新答案。这是因为在迁移过程中,您将这两个字段都指定为identity,此表不需要identity。请参阅我的编辑。
public partial class AddDependencies : DbMigration
{
    public override void Up()
    {
        AddColumn("dbo.Packages", "Package_ID", c => c.Int());
        CreateIndex("dbo.Packages", "Package_ID");
        AddForeignKey("dbo.Packages", "Package_ID", "dbo.Packages", "ID");
    }

    public override void Down()
    {
        DropForeignKey("dbo.Packages", "Package_ID", "dbo.Packages");
        DropIndex("dbo.Packages", new[] { "Package_ID" });
        DropColumn("dbo.Packages", "Package_ID");
    }
}
protected override void OnModelCreating(DbModelBuilder modelBuilder)
    {
        modelBuilder.Entity<Package>()
            .HasMany(p => p.Dependencies)
            .WithMany()
            .Map(m =>
            {
                m.MapLeftKey("Package_ID");
                m.MapRightKey("ID");
                m.ToTable("PackageDependency");
            });
}