如何使用 EF Core Code-First 在自身上桥接 table
How to bridge a table on itself using EF Core Code-First
这是我过去使用数据库优先方法多次完成的操作。我现在正在使用 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; }
}
和一个 Bridge 模型,它基本上在同一个 table:
中的两个 DataMapping 项之间创建关系
public class DataMappingRelation
{
[Key]
[Column(Order = 1)]
[DatabaseGenerated(DatabaseGeneratedOption.Identity)]
public long Id { get; set; }
[ForeignKey("DataMappingId")]
public long? DataMapping1Id { get; set; }
public DataMapping DataMapping1 { get; set; }
[ForeignKey("DataMappingId")]
public long? DataMapping2Id { get; set; }
public DataMapping DataMapping2 { get; set; }
}
但是这个调用不起作用:
return _context.DataMappings.Where(x => x.Model == type.FullName)
.Include(x=>x.DataMappingRelations)
.ToList();
它不喜欢 Include 并抛出空引用异常。
我在这里基本上需要做的就是针对给定的 "DataMapping" 根据 "DataMappingRelations" table.
中的关系获取所有相关的 DataMapping 项
是的,我看过 this answer,但同样,这是两个独立 table 的示例,而不是一个 table 桥接自身。
我怀疑我做错了这一切。我怎样才能让它工作?我发现的所有示例都桥接了两个单独的 table。这将桥接相同的 table.
它 many-to-many
with self 但你的整个配置看起来很乱。
所以首先,您的 DataMapping
模型 class 应该包含 DataMappingRelation
中两个外键的两个列表导航属性,如下所示:
public class DataMapping
{
......
public List<DataMappingRelation> DataMapping1Relations { get; set; }
public List<DataMappingRelation> DataMapping2Relations { get; set; }
.........
}
现在从 DataMapping1
和 DataMapping2
外键中删除 [ForeignKey("DataMappingId")]
属性,如下所示:
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; }
}
那么Fluent API
配置应该如下:
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);
}
这是我过去使用数据库优先方法多次完成的操作。我现在正在使用 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; }
}
和一个 Bridge 模型,它基本上在同一个 table:
中的两个 DataMapping 项之间创建关系public class DataMappingRelation
{
[Key]
[Column(Order = 1)]
[DatabaseGenerated(DatabaseGeneratedOption.Identity)]
public long Id { get; set; }
[ForeignKey("DataMappingId")]
public long? DataMapping1Id { get; set; }
public DataMapping DataMapping1 { get; set; }
[ForeignKey("DataMappingId")]
public long? DataMapping2Id { get; set; }
public DataMapping DataMapping2 { get; set; }
}
但是这个调用不起作用:
return _context.DataMappings.Where(x => x.Model == type.FullName)
.Include(x=>x.DataMappingRelations)
.ToList();
它不喜欢 Include 并抛出空引用异常。
我在这里基本上需要做的就是针对给定的 "DataMapping" 根据 "DataMappingRelations" table.
中的关系获取所有相关的 DataMapping 项是的,我看过 this answer,但同样,这是两个独立 table 的示例,而不是一个 table 桥接自身。
我怀疑我做错了这一切。我怎样才能让它工作?我发现的所有示例都桥接了两个单独的 table。这将桥接相同的 table.
它 many-to-many
with self 但你的整个配置看起来很乱。
所以首先,您的 DataMapping
模型 class 应该包含 DataMappingRelation
中两个外键的两个列表导航属性,如下所示:
public class DataMapping
{
......
public List<DataMappingRelation> DataMapping1Relations { get; set; }
public List<DataMappingRelation> DataMapping2Relations { get; set; }
.........
}
现在从 DataMapping1
和 DataMapping2
外键中删除 [ForeignKey("DataMappingId")]
属性,如下所示:
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; }
}
那么Fluent API
配置应该如下:
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);
}