简体   繁体   English

Entity Framework Core 添加唯一约束代码优先

[英]Entity Framework Core add unique constraint code-first

I can't find way to add a unique constraint to my field with using attribute:我找不到使用属性向我的字段添加唯一约束的方法:

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

I'm using these packages:我正在使用这些软件包:

 "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",

On EF core you cannot create Indexes using data annotations.But you can do it using the Fluent API.在 EF 核心上,您无法使用数据注释创建索引。但您可以使用 Fluent API 来完成。

Like this inside your {Db}Context.cs :像这样在您的{Db}Context.cs

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

...or if you're using the overload with the buildAction: ...或者如果您在 buildAction 中使用重载:

protected override void OnModelCreating(ModelBuilder builder)
{
    builder.Entity<User>(entity => {
        entity.HasIndex(e => e.Email).IsUnique();
    });
}

You can read more about it here : Indexes您可以在此处阅读更多相关信息: 索引

Also if you want to create Unique constrains on multiple columns you can simply do this (following @Sampath's link )此外,如果您想在多个列上创建唯一约束,您可以简单地执行此操作(按照@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; }
}

Solution for EF Core 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})
    }
}

DB table will look like this:数据库表将如下所示:

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 参考 EF Core 文档

Since Entity Framework Core (EF Core) 5.0 we can configure Unique Indexes via Data Annotations .从 Entity Framework Core (EF Core) 5.0 开始,我们可以通过 Data Annotations 配置唯一索引

It is little different to eg EF6, because we cannot set it on the property itself but instead on the class.它与例如 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; }
}

For further information on Indexes and Data Annotations see: https://docs.microsoft.com/en-us/ef/core/modeling/indexes?tabs=data-annotations有关索引和数据注释的更多信息,请参阅: https : //docs.microsoft.com/en-us/ef/core/modeling/indexes?tabs= data-annotations

To use it in EF core via model configuration通过模型配置在 EF 核心中使用它

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

Ef core support unique configuration. Ef 核心支持独特的配置。

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

Ef core support multiple unique keys ef core 支持多个唯一键

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

Don't forget run ef core command to make migration and update the database不要忘记运行 ef core 命令来进行迁移和更新数据库

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

The OP is asking about whether it is possible to add an Attribute to an Entity class for a Unique Key. OP 询问是否可以将属性添加到唯一键的实体类。 The short answer is that it IS possible, but not an out-of-the-box feature from the EF Core Team.简短的回答是它是可能的,但不是 EF Core 团队的开箱即用功能。 If you'd like to use an Attribute to add Unique Keys to your Entity Framework Core entity classes, you can do what I've posted here如果您想使用属性将唯一键添加到您的 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; }
}

For someone who is trying all these solution but not working try this one, it worked for me对于尝试所有这些解决方案但不起作用的人试试这个,它对我有用

protected override void OnModelCreating(ModelBuilder builder)
{

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

}

None of these methods worked for me in .NET Core 2.2 but I was able to adapt some code I had for defining a different primary key to work for this purpose.在 .NET Core 2.2 中,这些方法都不适合我,但我能够改编一些代码,用于定义不同的主键以实现此目的。

In the instance below I want to ensure the OutletRef field is unique:在下面的实例中,我想确保 OutletRef 字段是唯一的:

public class ApplicationDbContext : IdentityDbContext
    {
        protected override void OnModelCreating(ModelBuilder modelBuilder)
        {
            base.OnModelCreating(modelBuilder);
            modelBuilder.Entity<Outlet>()
                .HasIndex(o => new { o.OutletRef });
        }
    }

This adds the required unique index in the database.这会在数据库中添加所需的唯一索引。 What it doesn't do though is provide the ability to specify a custom error message.但它没有提供指定自定义错误消息的能力。

We can add Unique key index by using fluent api.我们可以使用 fluent api 添加唯一键索引。 Below code worked for me下面的代码对我有用

protected override void OnModelCreating(DbModelBuilder modelBuilder)
    {

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

    }

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM