将引用 属性 字段映射到与根 class 相同的 table

Map reference property fields to the same table as root class

我有参考属性的模型

internal class AstronomycalBody : IAstronomycalBody
{
    public long Id { get; set; }

    public string Name { get; set; }

    public Coord Coord { get; set; }

    public long Mass { get; set; }

    public double Speed { get; set; }

    public IAstronomycalBody CentralObject { get; set; }
}

public class Coord
{
    public long X { get; set; }

    public long Y { get; set; }

    public long Z { get; set; }
}

我想像这样使用映射

internal class AstronomycalBodyContext : DbContext
{
    public DbSet<AstronomycalBody> AstronomycalBody { get; set; }

    protected override void OnConfiguring(DbContextOptionsBuilder optionsBuilder)
    {
        optionsBuilder.UseSqlite(DbSettings.ConnectionString);
    }

    protected override void OnModelCreating(ModelBuilder modelBuilder)
    {
        modelBuilder.Entity<AstronomycalBody>().Property(p => p.Coord.X).ForSqliteHasColumnName("CoordX");
        modelBuilder.Entity<AstronomycalBody>().Property(p => p.Coord.Y).ForSqliteHasColumnName("CoordY");
        modelBuilder.Entity<AstronomycalBody>().Property(p => p.Coord.Z).ForSqliteHasColumnName("CoordZ");
        modelBuilder.Entity<AstronomycalBody>().Property(p => p.CentralObject.Id).ForSqliteHasColumnName("CentralObjectId");
    }
}

将模型映射到此 table:

目前,编译器正在抛出此异常...

您的 AstronomycalBody 不是有效的 EF 实体模型 class。

首先,EF Core does not support Complex/value types yet,因此 Coord 成员应该原地展开。

其次,EF 不适用于 interfaces,因此每个导航引用/集合元素类型都应为实体 class .

话虽这么说,但不确定您的 IAstronomycalBody 是什么样子以及如何实现它(您可能需要某些成员的 explicit 实现),但是实体 class 应该是这样的:

internal class AstronomycalBody //: IAstronomycalBody
{
    public long Id { get; set; }
    public string Name { get; set; }
    //public Coord Coord { get; set; }
    public long CoordX { get; set; }
    public long CoordY { get; set; }
    public long CoordZ { get; set; }
    public long Mass { get; set; }
    public double Speed { get; set; }
    public AstronomycalBody CentralObject { get; set; }
}

现在,由于按照惯例它将生成显示的 table,只需删除 OnModelCreating 中显示的所有行即可。