Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/277.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 通过连接表进行多对多自连接_C#_Entity Framework - Fatal编程技术网

C# 通过连接表进行多对多自连接

C# 通过连接表进行多对多自连接,c#,entity-framework,C#,Entity Framework,我有一个EF模型,可以通过中间类自我引用来定义父/子关系。我知道如何使用Map命令处理纯多对多关系,但由于某些原因,使用这个中间类会导致映射出现问题。中间类为关系提供其他属性。请参见下面的类、modelBinder逻辑和错误: public class Equipment { [Key] public int EquipmentId { get; set; } public virtual List<ChildRecord> Parents

我有一个EF模型,可以通过中间类自我引用来定义父/子关系。我知道如何使用Map命令处理纯多对多关系,但由于某些原因,使用这个中间类会导致映射出现问题。中间类为关系提供其他属性。请参见下面的类、modelBinder逻辑和错误:

public class Equipment
{        
    [Key]
    public int EquipmentId { get; set; }

    public virtual List<ChildRecord> Parents { get; set; }
    public virtual List<ChildRecord> Children { get; set; }
}

public class ChildRecord
{
    [Key]
    public int ChildId { get; set; }

    [Required]
    public int Quantity { get; set; }

    [Required]
    public Equipment Parent { get; set; }

    [Required]
    public Equipment Child { get; set; }
}

我已经看过了互联网上的各种其他答案,它们的共同点似乎是我在自我加入,因为我能找到的所有答案都是针对两种不同类型的


如果定义此类:

public class Equipment
{
    [Key]
    public int EquipmentId { get; set; }

    public virtual List<EquipmentRelation> Parents { get; set; }
    public virtual List<EquipmentRelation> Children { get; set; }
}

public class EquipmentRelation
{
    [Key]
    [Column("ChildId", Order=1)]
    public int ChildId { get; set; }

    [Key]
    [Column("ParentId", Order=2)]
    public int ParentId { get; set; }

    [Required]
    public int Quantity { get; set; }

    [Required]
    public Equipment Parent { get; set; }

    [Required]
    public Equipment Child { get; set; }
}
代码优先将正确推断设备件与其父项和子项之间的关系。父项和子项都是可选的。设备关系需要父项和子项

与原始代码的区别在于关联表包含一个复合键,该键具有父设备和子设备的PK。我把它改名为EquipmentRelation

当然,如果您想对其进行微调或编写文档,您可以使用fluentapi来表示推断的关系


注意:列属性是必需的,因为当您使用属性定义复合键时,EF需要知道键中列的顺序。或者,您可以使用Fluent API HasKey定义此键

我尝试了第二个映射modelBuilder.Entity。。。。没问题。EF 6.1.1,VS 2012。@GertArnold在从EF 6.0.2升级到6.1.1后,如您所建议的,在使用第二组时,错误消失了;但是,输出SQL表仍然有四个ID列,两个用于子项,两个用于父项。看起来它没有正确地看待这段关系。这很奇怪。我刚刚从头开始生成了一个数据库,我的ChildRecords表只有两个外键。@GertArnold scratch说。。。帮助您记住重建。。。现在它起作用了。我确实认为这是EF版本。如果你能发布一个答案,我很乐意接受。我理解你的意思,但我不明白它和我在代码中显示的有什么不同。我有两个一对多关系,带有返回父对象和子对象的导航属性以及附加列。我将它作为一个实体构建,它将与其他属性一起可访问。你能澄清一下你的答案,根据我在问题中包含的代码指出我们方法之间的差异吗?哦,对不起,我误读了你的代码。不过,我明天会给你一个解决方案。我现在时间不多。我为你的问题添加了一个有效的解决方案,并做了一些解释。
        modelBuilder.Entity<Equipment>()
            .HasMany(x => x.Parents)
            .WithRequired(x => x.Child)
            .WillCascadeOnDelete(false);

        modelBuilder.Entity<Equipment>()
            .HasMany(x => x.Children)
            .WithRequired(x => x.Parent)
            .WillCascadeOnDelete(false);
    [Required]
    [ForeignKey("EquipmentId")]
    public Equipment Parent { get; set; }

    [Required]
    [ForeignKey("EquipmentId")]
    public Equipment Child { get; set; }
    [InverseProperty("Child")]
    public virtual List<ChildRecord> Parents { get; set; }
    [InverseProperty("Parent")]
    public virtual List<ChildRecord> Children { get; set; }
public class Equipment
{
    [Key]
    public int EquipmentId { get; set; }

    public virtual List<EquipmentRelation> Parents { get; set; }
    public virtual List<EquipmentRelation> Children { get; set; }
}

public class EquipmentRelation
{
    [Key]
    [Column("ChildId", Order=1)]
    public int ChildId { get; set; }

    [Key]
    [Column("ParentId", Order=2)]
    public int ParentId { get; set; }

    [Required]
    public int Quantity { get; set; }

    [Required]
    public Equipment Parent { get; set; }

    [Required]
    public Equipment Child { get; set; }
}