Как определить составной первичный ключ для существующей таблицы базы данных?
=============================================================================

 Я работаю над проектом Core MVC, который считывает данные (без необходимости записи) из уже существующей базы данных. К сожалению, эта база данных является полным беспорядком, но я ничего не могу изменить в ней (и даже если бы мог, я бы не коснулся ее 10-футовым полюсом). 

 Некоторые из важных проблем базы данных следующие: 

* Таблицы не имеют отношения внешних ключей друг к другу и содержат данные, которые лучше всего были бы введены в подзапись; кто создал базу данных, похоже, использовал таблицы, как если бы они были таблицами Excel.
* Определенных первичных или внешних ключей нет.
* Имена таблиц и столбцов, по-видимому, являются инициалами содержащихся данных (для воображаемого примера таблица, которую обычно называют «Клиент», вместо этого будет называться «dbbc» для «Database - Business Customer»).
* Таблицы не находятся в схеме «dbo».

 Тем не менее я вынужден читать данные из этой базы данных и предпочел бы использовать Entity Framework для этого. 

 База данных размещена в **SQL Server 2008R2** . 

 Я мог бы заставить его работать без проблем в одной из таблиц, которые мне нужно использовать, используя атрибуты, такие как [Таблица], [Колонка] и [Ключ], чтобы использовать класс с соответствующими именами свойств, сопоставленными с именами реальных столбцов. Другая таблица, однако, является проблемой. 

 Эта таблица не имеет один столбец , который можно рассматривать как первичный ключ, но я обнаружил , что комбинация из двух колонок **является** уникальной для каждой строки, так что они могут рассматриваться в качестве составного первичного ключа (даже если они не определены как таких в базе данных). 

 Я определил класс следующим образом (я изменил имена, чтобы скрыть личность этой базы данных, насколько я бы хотел назвать и позор): 

```
[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] для обоих столбцов, которые составляют мнимый составной первичный ключ.
* Я добавил значение для свойства Order атрибута [Column], поскольку я прочитал, что это необходимо для составных клавиш.
* Я только сопоставил столбцы, которые мне нужно использовать, поскольку таблица имеет примерно в 10 раз больше столбцов, чем имеет отношение к этому проекту.

 Тем не менее, при попытке запустить проект возникает ошибка: 

>  InvalidOperationException: для типа объекта MyProject.Models.Order требуется определить первичный ключ. 
> 
> 

 Есть ли что-то еще, что я могу добавить, чтобы эта таблица работала с Entity Framework? 

 **EDIT:** Я обнаружил, что это работает, если я определяю его в методе `OnModelCreating` в контексте, например `modelBuilder.Entity<Order>().HasKey(ord => new { ord.OrderNo, ord.OrderLineNo });` , Однако я по-прежнему предпочитаю делать это только с атрибутами, если это возможно. 

 Ваша конфигурация отлично работает с EF6. Но вы должны быть осторожны при использовании Data Annotations с EF Core (похоже, Fluent API будет предпочтительным подходом там). 

 В разделе « [Ключи» (первичный)](https://docs.efproject.net/en/latest/modeling/keys.html#keys-primary) документации явно указано: 

>  Вы также можете использовать Fluent API для настройки нескольких свойств в качестве ключа объекта (известного как составной ключ). Композитные клавиши могут быть сконфигурированы только с использованием Fluent API - соглашения никогда не будут настраивать составной ключ, и вы не можете использовать Data Annotations для его настройки. 
> 
> 

 Поэтому вам действительно нужно использовать: 

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

```