C# 如何首先使用EF核心代码在表本身上桥接

C# 如何首先使用EF核心代码在表本身上桥接,c#,ef-code-first,entity-framework-core,C#,Ef Code First,Entity Framework Core,这是我过去使用数据库优先的方法做过多次的操作。我现在先用EF-Core来尝试代码,结果失败得很惨 我有以下型号: public class DataMapping { [Key] [Column(Order = 1)] [DatabaseGenerated(DatabaseGeneratedOption.Identity)] public long Id { get; set; } public string Model { get; set; }

这是我过去使用数据库优先的方法做过多次的操作。我现在先用EF-Core来尝试代码,结果失败得很惨

我有以下型号:

public class DataMapping
{
    [Key]
    [Column(Order = 1)]
    [DatabaseGenerated(DatabaseGeneratedOption.Identity)]
    public long Id { get; set; }

    public string Model { get; set; } 
    public string Property { get; set; }
    public bool IgnoreProperty { get; set; } 

    [NotMapped] //<-- I had to add this as the migration was complaining that it did not know what the relation was
    public List<DataMappingRelation> DataMappingRelations { get; set; }

    public DateTime DateCreated { get; set; } = DateTime.UtcNow;
    public DateTime? DateModified { get; set; }
}
但是,此呼叫不起作用:

return _context.DataMappings.Where(x => x.Model == type.FullName)
            .Include(x=>x.DataMappingRelations)
            .ToList();
它不喜欢Include并抛出null ref异常

这里我基本上需要做的是,对于给定的“DataMapping”,根据“DataMappingRelations”表中的关系获取所有相关的DataMapping项

是的,我已经看过了,但再次强调,这是一个两个独立表的例子,而不是一个单独的表本身桥接


我怀疑我做错了这一切。我怎样才能让它工作?我发现的所有例子都是连接两个独立的表。这将桥接同一个表。

它的
多对多
与self,但您的整个配置看起来很混乱

因此,首先,您的
DataMapping
模型类应该包含
DataMappingRelation
中两个外键的两个列表导航属性,如下所示:

public class DataMapping
{
    ......

    public List<DataMappingRelation> DataMapping1Relations { get; set; }

    public List<DataMappingRelation> DataMapping2Relations { get; set; }

    .........
}
public class DataMappingRelation
{
    [Key]
    [Column(Order = 1)]
    [DatabaseGenerated(DatabaseGeneratedOption.Identity)]
    public long Id { get; set; }

    public long? DataMapping1Id { get; set; }
    public DataMapping DataMapping1 { get; set; } 

    public long? DataMapping2Id { get; set; }
    public DataMapping DataMapping2 { get; set; }
}
protected override void OnModelCreating(ModelBuilder modelBuilder)
{
     base.OnModelCreating(modelBuilder);

     modelBuilder.Entity<DataMappingRelation>()
         .HasOne(dmr => dmr.DataMapping1)
         .WithMany(dm => dm.DataMapping1Relations)
         .HasForeignKey(dmr => dmr.DataMapping1Id)
         .OnDelete(DeleteBehavior.Restrict);

     modelBuilder.Entity<DataMappingRelation>()
         .HasOne(dmr => dmr.DataMapping2)
         .WithMany(dm => dm.DataMapping2Relations)
         .HasForeignKey(dmr => dmr.DataMapping2Id)
         .OnDelete(DeleteBehavior.Restrict);
}
然后
Fluent API
配置应如下所示:

public class DataMapping
{
    ......

    public List<DataMappingRelation> DataMapping1Relations { get; set; }

    public List<DataMappingRelation> DataMapping2Relations { get; set; }

    .........
}
public class DataMappingRelation
{
    [Key]
    [Column(Order = 1)]
    [DatabaseGenerated(DatabaseGeneratedOption.Identity)]
    public long Id { get; set; }

    public long? DataMapping1Id { get; set; }
    public DataMapping DataMapping1 { get; set; } 

    public long? DataMapping2Id { get; set; }
    public DataMapping DataMapping2 { get; set; }
}
protected override void OnModelCreating(ModelBuilder modelBuilder)
{
     base.OnModelCreating(modelBuilder);

     modelBuilder.Entity<DataMappingRelation>()
         .HasOne(dmr => dmr.DataMapping1)
         .WithMany(dm => dm.DataMapping1Relations)
         .HasForeignKey(dmr => dmr.DataMapping1Id)
         .OnDelete(DeleteBehavior.Restrict);

     modelBuilder.Entity<DataMappingRelation>()
         .HasOne(dmr => dmr.DataMapping2)
         .WithMany(dm => dm.DataMapping2Relations)
         .HasForeignKey(dmr => dmr.DataMapping2Id)
         .OnDelete(DeleteBehavior.Restrict);
}
模型创建时受保护的覆盖无效(ModelBuilder ModelBuilder)
{
基于模型创建(modelBuilder);
modelBuilder.Entity()
.HasOne(dmr=>dmr.DataMapping1)
.WithMany(dm=>dm.DataMapping1关系)
.HasForeignKey(dmr=>dmr.DataMapping1Id)
.OnDelete(DeleteBehavior.Restrict);
modelBuilder.Entity()
.HasOne(dmr=>dmr.DataMapping2)
.WithMany(dm=>dm.DataMapping2关系)
.HasForeignKey(dmr=>dmr.DataMapping2Id)
.OnDelete(DeleteBehavior.Restrict);
}