C# 实体框架编码同一表上的第一个多对多关系

C# 实体框架编码同一表上的第一个多对多关系,c#,entity-framework,C#,Entity Framework,这里有一个稍微奇怪的场景,我有一个实体和一个多对多表。下表是这样的: AssetHeader.cs [Table("AssetHeader", Schema = "assets")] public class AssetHeader { public Guid Id { get; set; } public virtual ICollection<AssetHeaderEquipment> AssetHeaders { get; set; } public

这里有一个稍微奇怪的场景,我有一个实体和一个多对多表。下表是这样的:

AssetHeader.cs

[Table("AssetHeader", Schema = "assets")]
public class AssetHeader
{
    public Guid Id { get; set; }

    public virtual ICollection<AssetHeaderEquipment> AssetHeaders { get; set; }

    public virtual ICollection<AssetHeaderEquipment> AssetEquipment { get; set; }
}
当我尝试使用代码优先迁移创建db时,我在SQL中得到以下结果:

如何首先获得代码以生成正确的db结构,我很乐意在dbcontext中使用attributes或fluent

更新: 按照Ivan Stoev的回答,结构如预期。但是,在设置字段时,现在会发生以下情况

试图保存的模型:

实际保存结果:

如何将AssetEquipment ID设置为AssetEquipment ID


我创建了一个非常轻量级的dojo项目,以实现完整的代码可见性。 你可以在这里找到:
这是EF无法自动配对关系导航属性的情况之一

通常可以使用
InverseProperty
属性或
Has
/
使用
fluent API解决。但是,由于这种类型的关系总是会引入“多级联路径”问题,这要求至少对其中一个关系关闭级联删除,并且这只能通过fluent API完成,因此除了使用fluent API之外别无选择(对于关系,IMHO无论如何都会更好)

最低要求是配置要关闭级联删除的关系。一旦你这样做了,EF通常会做剩下的事情

例如:

modelBuilder.Entity<AssetHeader>()
    .HasMany(e => e.AssetEquipment)
    .WithRequired(e => e.AssetEquipment)
    .WillCascadeOnDelete(false);
更新根据有问题的用例,正确的配对应该是:

Collection       Inverse          FK
==========       =========        ==============
AssetHeaders     AssetEquipment   AssetEquipmentId
AssetEquipment   AssetHeader      AssetHeaderId
因此,请删除具有误导性的
ForeignKey
属性,并使用以下完全明确的fluent配置:

modelBuilder.Entity<AssetHeader>()
    .HasMany(e => e.AssetHeaders)
    .WithRequired(e => e.AssetEquipment)
    .HasForeignKey(e => e.AssetEquipmentId)
    .WillCascadeOnDelete(false);

modelBuilder.Entity<AssetHeader>()
    .HasMany(e => e.AssetEquipment)
    .WithRequired(e => e.AssetHeader)
    .HasForeignKey(e => e.AssetHeaderId)
    .WillCascadeOnDelete(true);
modelBuilder.Entity()
.HasMany(e=>e.AssetHeaders)
.需要(e=>e.装配设备)
.HasForeignKey(e=>e.AssetEquipmentId)
.WillCascadeOnDelete(假);
modelBuilder.Entity()
.HasMany(e=>e.AssetEquipment)
.WithRequired(e=>e.AssetHeader)
.HasForeignKey(e=>e.AssetHeaderId)
.WillCascadeOnDelete(真);

这就是我期望从您的实体设计中得到的数据库模型。问题是什么?问题是,两个额外的AssetHeader_Id和AssetHeader_Id 1sorry,在进一步测试后仍然存在问题。。。在主要问题中添加的更改没有问题。首先确保我正确地映射了这些对。当前,
assetheadequipment.AssetEquipment
映射到
AssetHeader.AssetEquipment
集合,但您可能希望通过更改
将其映射到
AssetHeader.asseteaders
集合(这取决于
asseteaders
集合的含义)。HasMany(e=>e.AssetEquipment)
。有许多(e=>e.AssetHeaders)
。第二,请发布复制新版本的代码,而不是屏幕截图,因为我不能用简单的测试复制,并且可能有一些特定的东西在您的情况下。我删除了AssetHeaders集合,因为我现在实际上不需要它。我的迁移脚本与上面的相同,但仍然保存不正确。我将尝试运行一个非常简单的测试应用程序,为您提供更好的图片…我创建了一个非常轻量级的项目,您可以在这里找到:好的,这就是我所说的正确配对导航属性的意思。请参阅更新,它可以正确地与示例项目场景配合使用。
Collection       Inverse          FK
==========       =========        ==============
AssetHeaders     AssetEquipment   AssetEquipmentId
AssetEquipment   AssetHeader      AssetHeaderId
modelBuilder.Entity<AssetHeader>()
    .HasMany(e => e.AssetHeaders)
    .WithRequired(e => e.AssetEquipment)
    .HasForeignKey(e => e.AssetEquipmentId)
    .WillCascadeOnDelete(false);

modelBuilder.Entity<AssetHeader>()
    .HasMany(e => e.AssetEquipment)
    .WithRequired(e => e.AssetHeader)
    .HasForeignKey(e => e.AssetHeaderId)
    .WillCascadeOnDelete(true);