Вопрос по entity-framework – Entity Framework код первого уникального столбца

92

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

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

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

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

Ваш Ответ

5   ответов
-12

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

Unique UserName

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

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

Unique ID , I have added decoration [Key] over my column and done. Same solution as described here: https://msdn.microsoft.com/en-gb/data/jj591583.aspx

IE:

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

Alternative answers

используя аннотацию данных

[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");
Error: User Rate Limit Exceeded
Error: User Rate Limit ExceededKeyError: User Rate Limit ExceededUserNameError: User Rate Limit ExceededUserNameError: User Rate Limit ExceededUserIdError: User Rate Limit ExceededKeyError: User Rate Limit Exceeded
204

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

[Index(IsUnique=true)]

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

using System.ComponentModel.DataAnnotations.Schema;

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

Column 'x' in table 'dbo.y' is of a type that is invalid for use as a key column in an index.

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

SQL Server retains the 900-byte limit for the maximum total size of all index key columns."

(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;}
}

Update:

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

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

и используйте в своей модели Builder:

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

Update 2

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

Update 3

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

Update 4

ASP.NET Core Mvc 2.2 с EF Core:

[DatabaseGenerated(DatabaseGeneratedOption.Identity)]
public Guid Unique { get; set; }
Error: User Rate Limit Exceeded
Error: User Rate Limit Exceeded"There are no significant differences between creating a UNIQUE constraint and creating a unique index that is independent of a constraint. Data validation occurs in the same manner, and the query optimizer does not differentiate between a unique index created by a constraint or manually created. However, creating a UNIQUE constraint on the column makes the objective of the index clear." msdn.microsoft.com/en-us/library/ms187019.aspx
Error: User Rate Limit Exceededdocs.efproject.net/en/latest/modeling/…
Error: User Rate Limit Exceeded
Error: User Rate Limit Exceeded
5

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

9

Из вашего кода становится очевидным, что вы используете POCO. Иметь другой ключ не нужно: вы можете добавить индекс, как предложеноЮФО.
Если вы используете 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.

Error: User Rate Limit Exceeded
Error: User Rate Limit Exceeded
23

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

Error: User Rate Limit Exceeded
Error: User Rate Limit Exceeded
Error: User Rate Limit Exceeded

Похожие вопросы