实体框架核心首先添加唯一的约束代码

我找不到方法添加一个唯一的约束我的字段使用属性:

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",
237234 次浏览

在EF core上,不能使用数据注释创建索引。但你可以使用Fluent API。

就像在你的{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();
});
}

你可以在这里阅读更多关于它的信息:< >强指数< / >强

另外,如果你想在多个列上创建唯一的约束,你可以简单地这样做(遵循@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; }
}

对于那些尝试了所有这些方法但都不起作用的人来说,试试这个,它对我很有效

protected override void OnModelCreating(ModelBuilder builder)
{


builder.Entity<User>().Property(t => t.Email).HasColumnAnnotation("Index", new IndexAnnotation(new IndexAttribute("IX_EmailIndex") { IsUnique = true }));


}

EF芯解决方案

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})
}
}

DB表是这样的:

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)
);

Ref to EF Core docs

OP询问是否可以为唯一键添加一个属性到实体类中。简单的回答是,这是可能的,但不是EF核心团队的一个开箱即用的功能。 如果你想使用一个属性来为你的实体框架核心实体类添加唯一键,你可以做我发布的在这里

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

我们可以使用fluent api添加唯一键索引。下面的代码对我有用

protected override void OnModelCreating(DbModelBuilder modelBuilder)
{


modelBuilder.Entity<User>().Property(p => p.Email).HasColumnAnnotation("Index", new IndexAnnotation(new IndexAttribute("IX_EmailIndex") { IsUnique = true }));


}

在。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 });
}
}


在数据库中添加所需的唯一索引。 不过,它没有提供指定自定义错误消息的能力

通过模型配置在EF核心中使用它

public class ApplicationCompanyConfiguration : IEntityTypeConfiguration<Company>
{
public void Configure(EntityTypeBuilder<Company> builder)
{
builder.ToTable("Company");
builder.HasIndex(p => p.Name).IsUnique();
}
}

Ef核心支持独特配置。

protected override void OnModelCreating(ModelBuilder builder)
{
builder.Entity<Account>()
.HasIndex(account => account.Email)
.IsUnique();
}

Ef核心支持多个唯一键

protected override void OnModelCreating(ModelBuilder modelBuilder)
{
modelBuilder.Entity<Account>()
.HasKey(account => new { account.Id, account.Email, account.RoleId });
}

不要忘记执行ef core命令进行迁移和更新数据库

>> dotnet ef migrations add MigrationName -c YourDbContextName
>> dotnet ef database update -c YourDbContextName

由于实体框架核心(EF核心)5.0,我们可以通过数据注释配置唯一索引

它与例如EF6略有不同,因为我们不能在属性本身上设置它,而是在类上设置它。

[Index(nameof(EmailAddress), IsUnique = true)]
public class User
{
[Key]
public Guid Id { get; set; }


[Required]
public string FullName { get; set; }


[Required]
public string EmailAddress { get; set; }
}

有关索引和数据注释的更多信息,请参见:https://learn.microsoft.com/en-us/ef/core/modeling/indexes?tabs=data-annotations