Установка уникального ограничения с помощью fluent API?
Я пытаюсь построить сущность EF с кодом сначала, и EntityTypeConfiguration
использование fluent API. создание первичных ключей легко, но не так с ограничением уникальности. Я видел старые сообщения, которые предлагали выполнять собственные команды SQL для этого, но это, похоже, не соответствует цели. возможно ли это с EF6?
6 ответов:
On помощью ef6.2, вы можете использовать
HasIndex()
чтобы добавить индексы для миграции через fluent API.https://github.com/aspnet/EntityFramework6/issues/274
пример
modelBuilder .Entity<User>() .HasIndex(u => u.Email) .IsUnique();
On помощью ef6.1 далее, вы можете использовать
IndexAnnotation()
чтобы добавить индексы для миграции в вашем fluent API.http://msdn.microsoft.com/en-us/data/jj591617.aspx#PropertyIndex
вы необходимо добавить ссылку на:
using System.Data.Entity.Infrastructure.Annotations;
Простой Пример
вот простое использование, добавление индекса на
User.FirstName
свойстваmodelBuilder .Entity<User>() .Property(t => t.FirstName) .HasColumnAnnotation(IndexAnnotation.AnnotationName, new IndexAnnotation(new IndexAttribute()));
Практический Пример:
вот более реалистичный пример. Он добавляет уникальный индекс по нескольким свойствам:
User.FirstName
иUser.LastName
, С именем индекса "IX_FIrstNameLastName"modelBuilder .Entity<User>() .Property(t => t.FirstName) .IsRequired() .HasMaxLength(60) .HasColumnAnnotation( IndexAnnotation.AnnotationName, new IndexAnnotation( new IndexAttribute("IX_FirstNameLastName", 1) { IsUnique = true })); modelBuilder .Entity<User>() .Property(t => t.LastName) .IsRequired() .HasMaxLength(60) .HasColumnAnnotation( IndexAnnotation.AnnotationName, new IndexAnnotation( new IndexAttribute("IX_FirstNameLastName", 2) { IsUnique = true }));
в дополнение к ответу Йорро, это также может быть сделано с помощью атрибутов.
образца
int
введите уникальную комбинацию клавиш:[Index("IX_UniqueKeyInt", IsUnique = true, Order = 1)] public int UniqueKeyIntPart1 { get; set; } [Index("IX_UniqueKeyInt", IsUnique = true, Order = 2)] public int UniqueKeyIntPart2 { get; set; }
если тип данных
string
, потомMaxLength
атрибут должен быть добавлен:[Index("IX_UniqueKeyString", IsUnique = true, Order = 1)] [MaxLength(50)] public string UniqueKeyStringPart1 { get; set; } [Index("IX_UniqueKeyString", IsUnique = true, Order = 2)] [MaxLength(50)] public string UniqueKeyStringPart2 { get; set; }
если существует проблема разделения модели домена / хранилища, используя
Metadatatype
атрибут/класс может быть вариант: https://msdn.microsoft.com/en-us/library/ff664465%28v=pandp.50%29.aspx?f=255&MSPPError=-2147217396
быстрый пример консольного приложения:
using System.ComponentModel.DataAnnotations; using System.ComponentModel.DataAnnotations.Schema; using System.Data.Entity; namespace EFIndexTest { class Program { static void Main(string[] args) { using (var context = new AppDbContext()) { var newUser = new User { UniqueKeyIntPart1 = 1, UniqueKeyIntPart2 = 1, UniqueKeyStringPart1 = "A", UniqueKeyStringPart2 = "A" }; context.UserSet.Add(newUser); context.SaveChanges(); } } } [MetadataType(typeof(UserMetadata))] public class User { public int Id { get; set; } public int UniqueKeyIntPart1 { get; set; } public int UniqueKeyIntPart2 { get; set; } public string UniqueKeyStringPart1 { get; set; } public string UniqueKeyStringPart2 { get; set; } } public class UserMetadata { [Index("IX_UniqueKeyInt", IsUnique = true, Order = 1)] public int UniqueKeyIntPart1 { get; set; } [Index("IX_UniqueKeyInt", IsUnique = true, Order = 2)] public int UniqueKeyIntPart2 { get; set; } [Index("IX_UniqueKeyString", IsUnique = true, Order = 1)] [MaxLength(50)] public string UniqueKeyStringPart1 { get; set; } [Index("IX_UniqueKeyString", IsUnique = true, Order = 2)] [MaxLength(50)] public string UniqueKeyStringPart2 { get; set; } } public class AppDbContext : DbContext { public virtual DbSet<User> UserSet { get; set; } } }
вот метод расширения для установки уникальных индексов более свободно:
public static class MappingExtensions { public static PrimitivePropertyConfiguration IsUnique(this PrimitivePropertyConfiguration configuration) { return configuration.HasColumnAnnotation("Index", new IndexAnnotation(new IndexAttribute { IsUnique = true })); } }
использование:
modelBuilder .Entity<Person>() .Property(t => t.Name) .IsUnique();
будет генерировать миграции, такие как:
public partial class Add_unique_index : DbMigration { public override void Up() { CreateIndex("dbo.Person", "Name", unique: true); } public override void Down() { DropIndex("dbo.Person", new[] { "Name" }); } }
Src:создание уникального индекса с Entity Framework 6.1 fluent API
@coni2k ' s ответ правильный, однако вы должны добавить
[StringLength]
атрибут для его работы в противном случае вы получите недопустимое исключение ключа (пример ниже).[StringLength(65)] [Index("IX_FirstNameLastName", 1, IsUnique = true)] public string FirstName { get; set; } [StringLength(65)] [Index("IX_FirstNameLastName", 2, IsUnique = true)] public string LastName { get; set; }
к сожалению, это не поддерживается в Entity Framework. Это было на Дорожной карте для EF 6, но его отодвинули назад:Workitem 299: Уникальные Ограничения (Уникальные Индексы)