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

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

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

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

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

5 ответов


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

[Index(IsUnique=true)]

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

using System.ComponentModel.DataAnnotations.Schema;

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

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

причина в том, что это:

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

(from: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


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


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

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

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

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.


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


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

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

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

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

уникальный ID , Я добавил украшение [ключ] над моей колонкой и сделал. Такое же решение, как описано здесь: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");