我应该如何为现有数据库 table 定义复合主键?

How should I define a composite primary key for an existing database table?

我正在开发一个从预先存在的数据库中读取数据(无需写入)的 Core MVC 项目。不幸的是,这个数据库一团糟,但我无法更改其中的任何内容(即使我可以,我也不会用 10 英尺长的杆子碰它)。

数据库的一些相关问题如下:

尽管如此,我不得不从这个数据库中读取数据,并且更愿意使用 Entity Framework 来这样做。

数据库托管在SQL Server 2008R2

通过使用 [Table]、[Column] 和 [Key] 等属性,我可以使它在我必须使用的 table 之一上正常工作a class 具有正确的 属性 名称映射到真实的列名称。然而,另一个 table 被证明是一个问题。

这个 table 没有一个列可以被认为是主键,但我发现两列的组合 每一行唯一的, 因此它们可以被视为复合主键(即使它们在数据库中未定义为复合主键)。

我已经定义了一个 class 如下(我已经更改了名称以隐藏该数据库的身份,尽管我想命名和羞辱):

[Table("dbbo", Schema = "schema")]
public class Order
{
    [Key]
    [Column("order", Order = 0)]
    public string OrderNo { get; set; }

    [Key]
    [Column("order_line", Order = 1)]
    public string OrderLineNo { get; set; }

    [Column("qty")]
    public double Quantity { get; set; }

    [Column("pr")]
    public double Price { get; set; }
}

仍然,尝试 运行 项目会产生错误:

InvalidOperationException: The entity type 'MyProject.Models.Order' requires a primary key to be defined.

还有什么我可以添加来使这个 table 与 Entity Framework 一起工作吗?

编辑: 我发现如果我在上下文的 OnModelCreating 方法中定义它,它会起作用,比如 modelBuilder.Entity<Order>().HasKey(ord => new { ord.OrderNo, ord.OrderLineNo });。但是,如果可能的话,我仍然更喜欢单独使用属性。

您的配置适用于 EF6。但是在 EF Core 中使用数据注释时必须小心(看起来 Fluent API 将是那里的首选方法)。

文档的 Keys(primary) 部分明确指出:

You can also use the Fluent API to configure multiple properties to be the key of an entity (known as a composite key). Composite keys can only be configured using the Fluent API - conventions will never setup a composite key and you can not use Data Annotations to configure one.

所以你真的需要使用:

modelBuilder.Entity<Order>().HasKey(e => new { e.OrderNo, e.OrderLineNo });