EF Core:同时使用ID作为主键和外键

Bru*_*uim 2 c# entity-framework-core ef-model-builder

我有两个entites的,发展前景及人,我想要做的是使用Prospect.ID作为ProspectTable和是PersonID的外键的主键,我IDEIA是使用两个实体相同的ID而对需要的是PersonID的我展望实体.当潜在客户被保存在数据库中时,它会尝试保存PersonID,即使我没有在我的Prospect实体上拥有此属性,我想知道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); });
Run Code Online (Sandbox Code Playgroud)

这是在数据库上执行的内容:

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

PersonDTO:

public class PersonDto : DtoBase
{
    public PersonDto()
    {

    }

    public ProspectDto Prospect { get; set; }
}
Run Code Online (Sandbox Code Playgroud)

ProspectDTO:

public class ProspectDto : DtoBase
{
    public ProspectDto()
    {

    }

    public PersonDto Person { get; set; } = new PersonDto();
}
Run Code Online (Sandbox Code Playgroud)

DtoBase:

public abstract class DtoBase
{
    public Guid ID { get; protected set; }
}
Run Code Online (Sandbox Code Playgroud)

谢谢.

Dmi*_*try 8

仅使用属性,不使用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();
}
Run Code Online (Sandbox Code Playgroud)

我不知道ForeignKey在FluentAPI中有什么相同的东西.所有其他(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);
        });
}
Run Code Online (Sandbox Code Playgroud)

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


Dom*_*nik 6

这是@dmitry 解决方案的 FluentAPI 等效项:

// Model classes:
public abstract class DtoBase
{
    public Guid ID { get; protected set; }
}

public class PersonDto : DtoBase
{
    public ProspectDto Prospect { get; set; }
}

public class ProspectDto : DtoBase
{
    public PersonDto Person { get; set; } = new PersonDto();
}

-------------------------------------------------------------------

// DbContext's OnModelCreating override:
protected override void OnModelCreating(ModelBuilder modelBuilder)
{
    modelBuilder.Entity<ProspectDto>().HasOne(p => p.Person).WithOne().HasForeignKey<ProspectDto>(p => p.ID);
}
Run Code Online (Sandbox Code Playgroud)

  • Dominik,您忘记了 modelBuilder 之后的 .Entity&lt;ProspectDto&gt;() 。然后效果很好。所以,修复后我会投票...;-) (2认同)