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

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

当前回答

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

这将在数据库中添加所需的惟一索引。 但是它没有提供指定自定义错误消息的能力。

其他回答

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

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

参考EF Core文档

我们可以使用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 }));

    }

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

protected override void OnModelCreating(ModelBuilder builder)
{

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

}

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

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

using Microsoft.EntityFrameworkCore;           // for [Index] attribute
using System.ComponentModel.DataAnnotations;   // for [Key] and [Required] attributes

namespace FunWithDataAnnotations
{
    [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