Entity Framework Core добавляет уникальный код ограничения
Я не могу найти способ добавить уникальное ограничение в мое поле с помощью атрибута:
public class User
{
[Required]
public int Id { get; set; }
[Required]
// [Index("IX_FirstAndSecond", 2, IsUnique = true)] not supported by core
public string Email { get; set; }
[Required]
public string Password { get; set; }
}
Я использую эти пакеты:
"Microsoft.EntityFrameworkCore": "1.0.1",
"Microsoft.EntityFrameworkCore.SqlServer": "1.0.1",
"Microsoft.EntityFrameworkCore.SqlServer.Design": "1.0.1",
"Microsoft.EntityFrameworkCore.Tools": "1.0.0-preview2-final",
Ответы
Ответ 1
В ядре EF вы не можете создавать индексы с помощью аннотаций данных. Но вы можете сделать это с помощью Fluent API.
{Db}Context.cs
внутри вашего {Db}Context.cs
:
protected override void OnModelCreating(ModelBuilder builder)
{
builder.Entity<User>()
.HasIndex(u => u.Email)
.IsUnique();
}
... или если вы используете перегрузку с buildAction:
protected override void OnModelCreating(ModelBuilder builder)
{
builder.Entity<User>(entity => {
entity.HasIndex(e => e.Email).IsUnique();
});
}
Вы можете прочитать больше об этом здесь: Индексы
Ответ 2
Также, если вы хотите создать уникальные ограничения для нескольких столбцов, вы можете просто сделать это (следуя @Sampath ссылка)
class MyContext : DbContext
{
public DbSet<Person> People { get; set; }
protected override void OnModelCreating(ModelBuilder modelBuilder)
{
modelBuilder.Entity<Person>()
.HasIndex(p => new { p.FirstName, p.LastName })
.IsUnique(true);
}
}
public class Person
{
public int PersonId { get; set; }
public string FirstName { get; set; }
public string LastName { get; set; }
}
Ответ 3
Решение для EF Core
public class User
{
public int Id { get; set; }
public string Name { get; set; }
public string Passport { get; set; }
}
public class ApplicationContext : DbContext
{
public DbSet<User> Users { get; set; }
public ApplicationContext()
{
Database.EnsureCreated();
}
protected override void OnConfiguring(DbContextOptionsBuilder optionsBuilder)
{
optionsBuilder.UseSqlServer(@"Server=(localdb)\mssqllocaldb;Database=efbasicsappdb;Trusted_Connection=True;");
}
protected override void OnModelCreating(ModelBuilder modelBuilder)
{
modelBuilder.Entity<User>().HasAlternateKey(u => u.Passport);
//or: modelBuilder.Entity<User>().HasAlternateKey(u => new { u.Passport, u.Name})
}
}
Таблица БД будет выглядеть так:
CREATE TABLE [dbo].[Users] (
[Id] INT IDENTITY (1, 1) NOT NULL,
[Name] NVARCHAR (MAX) NULL,
[Passport] NVARCHAR (450) NOT NULL,
CONSTRAINT [PK_Users] PRIMARY KEY CLUSTERED ([Id] ASC),
CONSTRAINT [AK_Users_Passport] UNIQUE NONCLUSTERED ([Passport] ASC)
);
Ссылка на документацию EF Core
Ответ 4
Для тех, кто пытается все эти решения, но не работает, попробуйте этот, он работал для меня
protected override void OnModelCreating(ModelBuilder builder)
{
builder.Entity<User>().Property(t => t.Email).HasColumnAnnotation("Index", new IndexAnnotation(new IndexAttribute("IX_EmailIndex") { IsUnique = true }));
}
Ответ 5
ОП спрашивает, возможно ли добавить атрибут в класс сущности для уникального ключа. Короткий ответ: это возможно, но не из коробки от EF Core Team. Если вы хотите использовать атрибут для добавления уникальных ключей в ваши классы сущностей Entity Framework Core, вы можете сделать то, что я разместил здесь
public class Company
{
[Required]
[DatabaseGenerated(DatabaseGeneratedOption.Identity)]
public Guid CompanyId { get; set; }
[Required]
[UniqueKey(groupId: "1", order: 0)]
[StringLength(100, MinimumLength = 1)]
public string CompanyName { get; set; }
[Required]
[UniqueKey(groupId: "1", order: 1)]
[StringLength(100, MinimumLength = 1)]
public string CompanyLocation { get; set; }
}
Ответ 6
Ни один из этих методов не работал для меня в .NET Core 2.2, но я смог адаптировать некоторый код для определения другого первичного ключа для работы с этой целью.
В приведенном ниже примере я хочу убедиться, что поле OutletRef уникально:
public class ApplicationDbContext : IdentityDbContext
{
protected override void OnModelCreating(ModelBuilder modelBuilder)
{
base.OnModelCreating(modelBuilder);
modelBuilder.Entity<Outlet>()
.HasIndex(o => new { o.OutletRef });
}
}
Это добавляет необходимый уникальный индекс в базу данных. Чего он не делает, так это предоставит возможность указать пользовательское сообщение об ошибке.
Ответ 7
Мы можем добавить уникальный индекс ключа, используя свободный API. Ниже код работал для меня
protected override void OnModelCreating(DbModelBuilder modelBuilder)
{
modelBuilder.Entity<User>().Property(p => p.Email).HasColumnAnnotation("Index", new IndexAnnotation(new IndexAttribute("IX_EmailIndex") { IsUnique = true }));
}
Ответ 8
Чтобы использовать его в ядре EF через конфигурацию модели
public class ApplicationCompanyConfiguration : IEntityTypeConfiguration<Company>
{
public void Configure(EntityTypeBuilder<Company> builder)
{
builder.ToTable("Company");
builder.HasIndex(p => p.Name).IsUnique();
}
}