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

时间:2016-10-03 10:37:03

标签: sql-server entity-framework entity-framework-core composite-primary-key ef-database-first

我正在开发一个Core MVC项目,该项目从预先存在的数据库中读取数据(无需编写)。不幸的是,这个数据库完全混乱,但我无法改变其中的任何内容(即使我可以,我也不会用10英尺的杆子来触摸它。)

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

  • 这些表彼此之间没有任何外键关系,并且包含最好输入子表的数据;创建数据库的人似乎已经将表用作Excel电子表格。
  • 没有定义主键或外键。
  • 表和列的名称似乎是所包含数据的首字母(对于一个假想的例子,一个人通常会命名的表" Customer"将被命名为" dbbc&#34 ;对于"数据库 - 商业客户")。
  • 表格不在" dbo"架构。

然而,我被迫从这个数据库中读取数据,并且更愿意使用Entity Framework来实现这一目的。

数据库托管在 SQL Server 2008R2

我可以通过使用[Table],[Column]和[Key]等属性使用一个具有映射到真实列的适当属性名称的类,使其在我必须使用的其中一个表上没有问题。名。然而,另一张桌子被证明是一个问题。

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

我已经定义了类似以下的类(我已经更改了名称以隐藏此数据库的标识,就像我想要的名字和耻辱一样):

[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; }
}
  • 我已经为构成虚构复合主键的两列添加了[Key]属性。
  • 我已经为[Column]属性的Order属性添加了一个值,因为我读到了复合键所需的值。
  • 我只映射了我需要使用的列,因为该表的列数比该项目的列数多10倍。

但是,尝试运行该项目会产生错误:

  

InvalidOperationException:实体类型' MyProject.Models.Order'需要定义主键。

我可以添加更多内容以使此表与Entity Framework一起使用吗?

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

1 个答案:

答案 0 :(得分:10)

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

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

  

您还可以使用Fluent API将多个属性配置为实体的键(称为复合键)。复合键只能使用Fluent API进行配置 - 约定永远不会设置复合键,也不能使用数据注释来配置复合键。

所以你真的需要使用:

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