Установка уникального ограничения с помощью свободного API?
185
Я пытаюсь создать объект EF с помощью Code First и EntityTypeConfigurationсвободно использующего API. создавать первичные ключи легко, но не так с уникальным ограничением. Я видел старые посты, в которых предлагалось выполнить собственные команды SQL для этого, но, похоже, это не соответствует цели. это возможно с EF6?
Вот более реалистичный пример. Он добавляет уникальный индекс для нескольких свойств: User.FirstNameи User.LastNameс именем индекса "IX_FirstNameLastName"
Это необходимо для обозначения аннотации столбца как «Индекс»! Я написал другое имя, и оно не сработало! Я потратил часы, прежде чем попытаться переименовать его в оригинальный «Индекс», как в вашем посте, и понял, что это важно. :( В нем должна быть константа, чтобы не жестко кодировать строку.
Александр Васильев
10
@AlexanderVasilyev Константа определяется какIndexAnnotation.AnnotationName
Натан
3
@ Натан Спасибо! Это оно! Пример в этом посте должен быть исправлен с помощью этой константы.
Александр Васильев
2
Не могу найти его в EF7 - DNX
Shimmy Weitzhandler
2
Я считаю, что IsUnique необходимо установить в true при создании IndexAttribute в первом примере. Как это: new IndexAttribute() { IsUnique = true }. В противном случае он создает только обычный (неуникальный) индекс.
Якубка
134
В дополнение к ответу Йорро, это можно сделать с помощью атрибутов.
using System.ComponentModel.DataAnnotations;
using System.ComponentModel.DataAnnotations.Schema;
using System.Data.Entity;
namespace EFIndexTest{classProgram{staticvoidMain(string[] args){
using (var context =newAppDbContext()){var newUser =newUser{UniqueKeyIntPart1=1,UniqueKeyIntPart2=1,UniqueKeyStringPart1="A",UniqueKeyStringPart2="A"};
context.UserSet.Add(newUser);
context.SaveChanges();}}}[MetadataType(typeof(UserMetadata))]publicclassUser{publicintId{get;set;}publicintUniqueKeyIntPart1{get;set;}publicintUniqueKeyIntPart2{get;set;}publicstringUniqueKeyStringPart1{get;set;}publicstringUniqueKeyStringPart2{get;set;}}publicclassUserMetadata{[Index("IX_UniqueKeyInt",IsUnique=true,Order=1)]publicintUniqueKeyIntPart1{get;set;}[Index("IX_UniqueKeyInt",IsUnique=true,Order=2)]publicintUniqueKeyIntPart2{get;set;}[Index("IX_UniqueKeyString",IsUnique=true,Order=1)][MaxLength(50)]publicstringUniqueKeyStringPart1{get;set;}[Index("IX_UniqueKeyString",IsUnique=true,Order=2)][MaxLength(50)]publicstringUniqueKeyStringPart2{get;set;}}publicclassAppDbContext:DbContext{publicvirtualDbSet<User>UserSet{get;set;}}}
Нет, если вы хотите полностью отделить модель своего домена от проблем хранения.
Рикард Лильеберг
4
Вы также должны убедиться, что у вас есть ссылка на EntityFramework
Майкл Транчида
2
Было бы хорошо, если бы атрибут Index был отделен от Entity Framework, чтобы я мог включить его в свой проект Models. Я понимаю, что это проблема хранения, но главная причина, по которой я ее использую, заключается в том, чтобы наложить уникальные ограничения на такие вещи, как имена пользователей и имена ролей.
Сэм
2
Не могу найти его в EF7 - DNX
Shimmy Weitzhandler
4
Это работает, только если вы также ограничиваете длину строки, так как SQL не позволяет использовать nvarchar (max) в качестве ключа.
JMK
17
Вот метод расширения для более быстрой установки уникальных индексов:
Ответ @ coni2k правильный, но вы должны добавить [StringLength]атрибут, чтобы он работал, иначе вы получите недопустимое исключение ключа (пример ниже).
IndexAnnotation.AnnotationName
new IndexAttribute() { IsUnique = true }
. В противном случае он создает только обычный (неуникальный) индекс.В дополнение к ответу Йорро, это можно сделать с помощью атрибутов.
Образец для
int
типа уникальной комбинации клавиш:Если тип данных
string
, тоMaxLength
атрибут должен быть добавлен:Если существует проблема разделения модели домен / хранилище, можно использовать
Metadatatype
атрибут / класс: https://msdn.microsoft.com/en-us/library/ff664465%28v=pandp.50%29.aspx?f= 255 & MSPPError = -2147217396Пример быстрого консольного приложения:
источник
Вот метод расширения для более быстрой установки уникальных индексов:
Использование:
Будет генерировать миграцию, такую как:
Src: Создание уникального индекса с помощью API-интерфейса Entity Framework 6.1.
источник
Ответ @ coni2k правильный, но вы должны добавить
[StringLength]
атрибут, чтобы он работал, иначе вы получите недопустимое исключение ключа (пример ниже).источник
К сожалению, это не поддерживается в Entity Framework. Это было на дорожной карте для EF 6, но это было оттеснено: Workitem 299: Уникальные Ограничения (Уникальные Индексы)
источник
источник