【问题标题】:How to use foreign key as composite key in EF Core 2?如何在 EF Core 2 中使用外键作为复合键?
【发布时间】:2019-01-18 12:09:30
【问题描述】:

我在 EF Core 2 中有几个课程。 1) 类服务器

  • 具有 id 作为 Guid 类型。它是一个主键,自动递增。

2) SerStaHis 类

  • 有 SerId 作为 Guid 类型。它是 Class Ser 的外键。它是一个带时间戳的主键

  • 有时间戳。它是带有 SerId 的主键

我使用 EF Core 2 构建了上面的两个表。我使用复合键功能将 SerStaHis.timestamp 和 SerStaHis.SerId 组合为主键。

我还在 Class Ser 中使用 ForeignKey 属性。 问题是我已设法将外键映射到 SerStaHis 类,但我无法将该外键与 SerStaHis.timestamp 结合作为主键。

这里是 Class Ser、Class SerStaHis 和 OnModelCreating 方法的代码 sn-ps。

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

这是我迁移到 SQL 时得到的实际结果:
(来源:pbrd.co

我在 SQL 中的预期结果如下:
(来源:pbrd.co

如果您需要更多说明,请告诉我。

我可以用 FluentAPI 方法完成上述任务吗?

如何使用外键作为复合主键?

谢谢

【问题讨论】:

    标签: c# foreign-keys entity-framework-core composite-primary-key ef-core-2.0


    【解决方案1】:

    改变

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

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

    ForeignKey 属性在应用于 FK 属性、引用导航属性和集合导航属性时的工作方式不同。当应用于集合导航属性时,它指定相关对象的外键属性名称。

    我个人觉得ForeignKey 属性令人困惑且容易出错。 Fluent API 更直观,并提供更好的控制。您的场景的流畅配置是这样的:

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

    【讨论】:

    • 如何将 serStaHis.service_id 中的外键设置为在 fluent api 和属性中都不能为空?
    • 值类型(例如GuidintDateTime 等)始终不可为空,因此您无需设置任何内容。如果您有string 或可为空的类型(Guid?int? 等)并且由于某种原因需要使其成为必需,那么请使用Required 属性或IsRequired fluent API。
    猜你喜欢
    • 2019-06-23
    • 2018-10-28
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2020-06-07
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多