简体   繁体   中英

How to use foreign key as composite key in EF Core 2?

I have several classes in EF Core 2. 1) Class Ser

  • has id as Guid type. It is a primary key, auto-incremented.

2) Class SerStaHis

  • has SerId as Guid type. It is a foreign key to Class Ser. It is a primary key with timestamp

  • has timestamp. It is a primary key with SerId

I use EF Core 2 to build two tables above. I have used Composite Key feature to combine SerStaHis.timestamp and SerStaHis.SerId as primary key.

I also use ForeignKey attribute in Class Ser. The problem is I have managed to map the foreign key to Class SerStaHis, but I could not combine that foreign key with SerStaHis.timestamp as a primary key.

Here are code snippets for Class Ser, Class SerStaHis and OnModelCreating method.

public class Ser {
    [Key]
    [DatabaseGenerated(DatabaseGeneratedOption.Identity)]   // auto-incrementing feature
    public Guid id { get; set; }

    //nav/foreign keys
    [ForeignKey("id")]
    public virtual ICollection<SerStaHis> SerStaHis{ get; set; }
}

public class SerStaHis{
    [Required] // maybe this is wrong as I got a foreign key from Class Ser
    public Guid service_id { get; set; }
    [Required]
    public DateTime timestamp { get; set; }
}

protected override void OnModelCreating(ModelBuilder modelBuilder) {
        base.OnModelCreating(modelBuilder);

        // composite primary keys method. // https://docs.microsoft.com/en-us/ef/core/modeling/keys
        modelBuilder.Entity<SerStaHis>()
            .HasKey(c => new {c.service_id, c.timestamp});
    }

Here is the actual result I got when I migrate to SQL: 实际结果
(source: pbrd.co )

My expected result in SQL is as followed: 预期结果
(source: pbrd.co )

Please let me know if you need more clarification.

Can I do the task above in FluentAPI method?

How do I use the foreign key as composite primary key?

Thank you

Change

[ForeignKey("id")]
public virtual ICollection<SerStaHis> SerStaHis{ get; set; }

to

[ForeignKey("service_id")]
public virtual ICollection<SerStaHis> SerStaHis{ get; set; }

ForeignKey attribute works differently when applied on the FK property, reference navigation property and collection navigation property. When applied on collection navigation property, it specifies the FK property name of the related object.

I personally find ForeignKey attribute confusing and error prone. Fluent API is much more intuitive and provides much better control. The fluent configuration for your scenario is like this:

modelBuilder.Entity<Ser>()
    .HasMany(ser => ser.SerStaHis) // collection navigation property
    .WithOne() // no reference navigation property
    .HasForeignKey(serStaHis => serStaHis.service_id); // foreign key property

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM