web-dev-qa-db-ja.com

EFコア:IDを主キーと外部キーとして同時に使用する

私にはProspectとpersonの2つのエンティティがあります。私がやろうとしているのは、ProspectTableの主キーとしてProspect.IDを使用し、PersonIDの外部キーとして使用することです。私のアイデアは、PersonIDを必要とせずに両方のエンティティに同じIDを使用することです。見込み客エンティティ。プロスペクトがデータベースに保存されているとき、プロスペクトエンティティにこのプロパティがなくてもPersonIDを保存しようとします。efcoreがこの種の関係をサポートしているかどうかを知りたいです。

これが私のモデルビルダーで得たものです。

_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)

PersonDTO:

_public class PersonDto : DtoBase
{
    public PersonDto()
    {

    }

    public ProspectDto Prospect { get; set; }
}
_

ProspectDTO:

_public class ProspectDto : DtoBase
{
    public ProspectDto()
    {

    }

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

DtoBase:

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

ありがとう。

6
Bruno Joaquim

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)は構成可能ですが、なぜ1つではなく2つのメソッドを使用するのですか。

上記のコードは、次の移行コードを生成します。

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);
        });
}

必要なものに非常に近いように見えます。

9
Dmitry

@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.HasOne(p => p.Person).WithOne().HasForeignKey<ProspectDto>(p => p.ID);
}
2
Dominik