Я использую Entity Framework 5.0 Code First;
public class Entity
{
[Key, DatabaseGenerated(DatabaseGeneratedOption.Identity)]
public string EntityId { get; set;}
public int FirstColumn { get; set;}
public int SecondColumn { get; set;}
}
Я хочу сделать сочетание между FirstColumn
и SecondColumn
как уникальным.
Пример:
Id FirstColumn SecondColumn
1 1 1 = OK
2 2 1 = OK
3 3 3 = OK
5 3 1 = THIS OK
4 3 3 = GRRRRR! HERE ERROR
Есть ли способ сделать это?
entity-framework
ef-code-first
constraints
multiple-columns
unique-key
Бассам Алугили
источник
источник
Я нашел три способа решения проблемы.
Уникальные индексы в EntityFramework Core:
Первый подход:
Второй подход к созданию уникальных ограничений с помощью EF Core с использованием альтернативных ключей.
Примеры
Один столбец:
Несколько столбцов:
EF 6 и ниже:
Первый подход:
Этот подход очень быстрый и полезный, но главная проблема в том, что Entity Framework ничего не знает об этих изменениях!
Второй подход:
я нашел это в этом посте, но сам не пробовал.
Проблема этого подхода заключается в следующем: он нуждается в DbMigration, что вы будете делать, если у вас его нет?
Третий подход:
я думаю, что это лучший, но для этого нужно время. Я просто покажу вам идею, лежащую в основе этого: в этой ссылке http://code.msdn.microsoft.com/CSASPNETUniqueConstraintInE-d357224a вы можете найти код для аннотации уникальных ключевых данных:
Проблема для этого подхода; Как я могу их объединить? У меня есть идея расширить эту реализацию Microsoft, например:
Позже в IDatabaseInitializer, как описано в примере Microsoft, вы можете комбинировать ключи в соответствии с заданным целым числом. Однако следует отметить одну вещь: если уникальное свойство имеет тип string, то вы должны установить MaxLength.
источник
CREATE UNIQUE INDEX ix_{1}_{2} ON {0} ({1}, {2})
? (см. BOL )Если вы используете Code-First , вы можете реализовать собственное расширение HasUniqueIndexAnnotation
Тогда используйте это так:
Что приведет к этой миграции:
И в конечном итоге в базе данных, как:
источник
this.Property(t => t.Email)
), что это за класс? (то есть: что этоthis
)EntityTypeConfiguration<T>
Вам нужно определить составной ключ.
С аннотациями данных это выглядит так:
Вы также можете сделать это с modelBuilder при переопределении OnModelCreating, указав:
источник
Ответ от niaher о том, что для использования свободного API вам нужно собственное расширение, может быть правильным на момент написания. Теперь вы можете (EF core 2.1) использовать свободный API следующим образом:
источник
Завершение ответа @chuck для использования составных индексов с внешними ключами .
Вам необходимо определить свойство, которое будет содержать значение внешнего ключа. Затем вы можете использовать это свойство внутри определения индекса.
Например, у нас есть компания с сотрудниками, и только у нас есть уникальное ограничение (имя, компания) для любого сотрудника:
Теперь отображение класса Employee:
Обратите внимание, что я также использовал расширение @niaher для уникальной аннотации индекса.
источник
В принятом ответе @chuck есть комментарий о том, что в случае с FK это не сработает.
у меня сработало, дело EF6 .Net4.7.2
источник
Я предполагаю, что вы всегда хотите
EntityId
быть первичным ключом, поэтому замена его составным ключом не вариант (хотя бы потому, что с составными ключами гораздо сложнее работать и потому что не очень разумно иметь первичные ключи, которые также имеют значение в бизнес-логике).Минимум, что вам нужно сделать, - это создать уникальный ключ в обоих полях базы данных и, в частности, проверить наличие исключений нарушения уникального ключа при сохранении изменений.
Кроме того, вы можете (должны) проверить уникальные значения перед сохранением изменений. Лучший способ сделать это с помощью
Any()
запроса, поскольку он минимизирует объем передаваемых данных:Остерегайтесь, что одной этой проверки никогда не бывает достаточно. Между проверкой и фактической фиксацией всегда есть некоторая задержка, поэтому вам всегда потребуется уникальное ограничение + обработка исключений.
источник
Недавно добавили составной ключ с уникальностью 2 столбцов, используя подход, рекомендованный 'chuck', спасибо @chuck. Только этот подход выглядел чище для меня:
источник