我有两个实体,即Prospect和person,我想做的是将Prospect.ID用作ProspectTable的主键,作为PersonID的外键,我的想法是两个实体都使用相同的ID,而我的不需要PersonID潜在客户实体。当潜在客户保存在数据库中时,即使我在Prospect实体上没有此属性,它也会尝试保存PersonID,我想知道ef核心是否支持这种关系。

这就是我在模型构建器上得到的。

modelBuilder.Entity<ProspectDto>(builder => { builder.ToTable("Prospects"); builder.HasKey(prospect => prospect.ID); });

modelBuilder.Entity<PersonDto>(builder => { builder.HasOne(p => p.Prospect).WithOne().HasForeignKey<ProspectDto>(pe => pe.ID); });


这是在数据库上执行的操作:

INSERT INTO [Prospects] ([ID], [PersonID]) VALUES (@p421, @p422)

人DTO:

public class PersonDto : DtoBase
{
    public PersonDto()
    {

    }

    public ProspectDto Prospect { get; set; }
}


前景DTO:

public class ProspectDto : DtoBase
{
    public ProspectDto()
    {

    }

    public PersonDto Person { get; set; } = new PersonDto();
}


DtoBase:

public abstract class DtoBase
{
    public Guid ID { get; protected set; }
}


谢谢。

最佳答案

仅使用属性,不使用FluentAPI:

public abstract class DtoBase
{
    [Key]
    public Guid ID { get; protected set; }
}

public class PersonDto : DtoBase
{
    [InverseProperty("Person")]
    public ProspectDto Prospect { get; set; }
}

public class ProspectDto : DtoBase
{
    [ForeignKey("ID")]           // "magic" is here
    public PersonDto Person { get; set; } = new PersonDto();
}


我不知道FluentAPI中的ForeignKey是什么。其他所有(Key和InverseProperty)都是可配置的,但是为什么要使用两种方法代替一种。

上面的代码生成以下迁移代码:

protected override void Up(MigrationBuilder migrationBuilder)
{
    migrationBuilder.CreateTable(
        name: "Persons",
        columns: table => new
        {
            ID = table.Column<Guid>(nullable: false)
        },
        constraints: table =>
        {
            table.PrimaryKey("PK_Persons", x => x.ID);
        });

    migrationBuilder.CreateTable(
        name: "Prospects",
        columns: table => new
        {
            ID = table.Column<Guid>(nullable: false)
        },
        constraints: table =>
        {
            table.PrimaryKey("PK_Prospects", x => x.ID);
            table.ForeignKey(
                name: "FK_Prospects_Persons_ID",
                column: x => x.ID,
                principalTable: "Persons",
                principalColumn: "ID",
                onDelete: ReferentialAction.Cascade);
        });
}


看起来非常接近您的需求。

10-07 23:32