Первый уникальный столбец Entity Framework

Я использую Entity Framework 4.3 и используя Code Fist.

У меня есть класс

public class User
{
   public int UserId{get;set;}
   public string UserName{get;set;}
}

Как сообщить Entity Framework, что UserName должно быть уникальным при создании таблицы базы данных? Я предпочел бы использовать аномалии данных вместо файла конфигурации, если это возможно.

Ответ 1

Решение для EF4.3

Уникальное имя пользователя

Добавить аннотацию данных по столбцу как:

 [Index(IsUnique = true)]
 [MaxLength(255)] // for code-first implementations
 public string UserName{get;set;}

Уникальный идентификатор ,  Я добавил украшение [Key] над моей колонкой и сделал.  Такое же решение, как описано здесь: https://msdn.microsoft.com/en-gb/data/jj591583.aspx

IE:

[Key]
public int UserId{get;set;}

Альтернативные ответы

с использованием аннотации данных

[Key, DatabaseGenerated(DatabaseGeneratedOption.Identity)]
[Column("UserId")]

с использованием отображения

  mb.Entity<User>()
            .HasKey(i => i.UserId);
        mb.User<User>()
          .Property(i => i.UserId)
          .HasDatabaseGeneratedOption(DatabaseGeneratedOption.Identity)
          .HasColumnName("UserId");

Ответ 2

В Entity Framework 6. 1+ вы можете использовать этот атрибут в вашей модели:

[Index(IsUnique=true)]

Вы можете найти его в этом пространстве имен:

using System.ComponentModel.DataAnnotations.Schema;

Если в качестве поля модели используется строка, убедитесь, что в SQL Server не установлено значение nvarchar (MAX), иначе вы увидите эту ошибку в коде Entity Framework First:

Столбец "x" в таблице "dbo.y" относится к типу, который недопустим для использования в качестве ключевого столбца в индексе.

Причина в следующем:

SQL Server сохраняет ограничение в 900 байт для максимального общего размера всех столбцов ключа индекса. "

(от: http://msdn.microsoft.com/en-us/library/ms191241.aspx)

Вы можете решить эту проблему, установив максимальную длину строки в вашей модели:

[StringLength(450)]

Ваша модель теперь будет выглядеть в EF CF 6. 1+:

public class User
{
   public int UserId{get;set;}
   [StringLength(450)]
   [Index(IsUnique=true)]
   public string UserName{get;set;}
}

Обновление:

если вы используете свободно:

  public class UserMap : EntityTypeConfiguration<User>
  {
    public UserMap()
    {
      // ....
      Property(x => x.Name).IsRequired().HasMaxLength(450).HasColumnAnnotation("Index", new IndexAnnotation(new[] { new IndexAttribute("Index") { IsUnique = true } }));
    }
  }

и используйте его в своем ModelBuilder:

protected override void OnModelCreating(DbModelBuilder modelBuilder)
{
  // ...
  modelBuilder.Configurations.Add(new UserMap());
  // ...
}

Обновление 2

для EntityFrameworkCore см. также эту тему: https://github.com/aspnet/EntityFrameworkCore/issues/1698

Обновление 3

для EF6.2 см.: https://github.com/aspnet/EntityFramework6/issues/274

Обновление 4

ASP.NET Core Mvc 2.2 с EF Core:

[DatabaseGenerated(DatabaseGeneratedOption.Identity)]
public Guid Unique { get; set; }

Ответ 3

EF не поддерживает уникальные столбцы, кроме ключей. Если вы используете EF Migrations, вы можете заставить EF создать уникальный индекс в столбце UserName (в коде миграции, а не какой-либо аннотации), но уникальность будет применяться только в базе данных. Если вы попытаетесь сохранить дублирующее значение, вам придется поймать исключение (нарушение ограничений), запущенное базой данных.

Ответ 4

Из вашего кода становится очевидным, что вы используете POCO. Отсутствует другой ключ: вы можете добавить индекс, как предлагается juFo.
Если вы используете Fluent API вместо атрибута UserName, ваша аннотация столбца должна выглядеть так:

this.Property(p => p.UserName)
    .HasColumnAnnotation("Index", new IndexAnnotation(new[] { 
        new IndexAttribute("Index") { IsUnique = true } 
    }
));

Это создаст следующий SQL script:

CREATE UNIQUE NONCLUSTERED INDEX [Index] ON [dbo].[Users]
(
    [UserName] ASC
)
WITH (
    PAD_INDEX = OFF, 
    STATISTICS_NORECOMPUTE = OFF, 
    SORT_IN_TEMPDB = OFF, 
    IGNORE_DUP_KEY = OFF, 
    DROP_EXISTING = OFF, 
    ONLINE = OFF, 
    ALLOW_ROW_LOCKS = ON, 
    ALLOW_PAGE_LOCKS = ON
) ON [PRIMARY]

Если вы попытаетесь вставить несколько пользователей с тем же именем пользователя, вы получите исключение DbUpdateException со следующим сообщением:

Cannot insert duplicate key row in object 'dbo.Users' with unique index 'Index'. 
The duplicate key value is (...).
The statement has been terminated.

И снова аннотации столбцов недоступны в Entity Framework до версии 6.1.

Ответ 5

Обратите внимание, что в Entity Framework 6.1 (в настоящее время в бета-версии) поддержка IndexAttribute будет аннотировать свойства индекса, которые автоматически приведут к (уникальному) индексу в ваших первых переходах кода.

Ответ 6

В EF 6.2 с использованием FluentAPI вы можете использовать HasIndex()

modelBuilder.Entity<User>().HasIndex(u => u.UserName).IsUnique();