Entity framework core 实体框架核心3.1代码优先唯一约束不起作用

Entity framework core 实体框架核心3.1代码优先唯一约束不起作用,entity-framework-core,code-first,unique-constraint,Entity Framework Core,Code First,Unique Constraint,这个问题很清楚。下面是我在dbContext类中的OnModelCreating方法: modelBuilder.Entity<States>(entity => { entity.ToTable("States"); modelBuilder.Entity<States>() .HasIndex(p => new { p.State })

这个问题很清楚。下面是我在
dbContext
类中的
OnModelCreating
方法:

modelBuilder.Entity<States>(entity =>
            {
                entity.ToTable("States");

                modelBuilder.Entity<States>()
                .HasIndex(p => new { p.State })
                .HasFilter("[State] IS NOT NULL")
                .HasFilter("[Code] IS NOT NULL")
                .IncludeProperties(p => new
                {
                    p.Code
                })
                .IsUnique();
下面是我对正在生成的表的SQL查询:

protected override void Up(MigrationBuilder migrationBuilder)
{
        migrationBuilder.CreateTable(
            name: "States",
            columns: table => new
            {
                Id = table.Column<int>(nullable: false)
                    .Annotation("SqlServer:Identity", "1, 1"),
                State = table.Column<string>(maxLength: 30, nullable: true),
                Code = table.Column<string>(maxLength: 3, nullable: true),
                Description = table.Column<string>(nullable: true)
            },
            constraints: table =>
            {
                table.PrimaryKey("PK_States", x => x.Id);
            });

        migrationBuilder.CreateIndex(
            name: "IX_States_State",
            table: "States",
            column: "State",
            unique: true,
            filter: "[Code] IS NOT NULL")
            .Annotation("SqlServer:Include", new[] { "Code" });
}
CREATE TABLE [dbo].[States]
(
    [Id] [INT] IDENTITY(1,1) NOT NULL,
    [State] [NVARCHAR](30) NULL,
    [Code] [NVARCHAR](3) NULL,
    [Description] [NVARCHAR](MAX) NULL,

    CONSTRAINT [PK_States] 
        PRIMARY KEY CLUSTERED ([Id] ASC)
                    WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, 
                          IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS = ON, 
                          ALLOW_PAGE_LOCKS = ON) ON [PRIMARY]
) ON [PRIMARY] TEXTIMAGE_ON [PRIMARY]
GO
正如您所看到的,这些列不是唯一的,可以为null


我这里缺少什么?

首先,由于您希望列和状态代码不可为空,因此需要使用注释声明它
[必需]

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

[Required]
public string State {get;set;}
以上内容将使列不可为空

列的唯一组合:

entity
    .HasIndex(p => new { p.State, p.Code })
    .IsUnique();
以上是唯一的办法。为了使列的组合唯一,必须对这两个列进行索引。包含的属性将不起作用。我还删除了HasFilter,因为该列现在是不可为null的。只获取非null结果的筛选器没有任何用处

编辑:

每列都是唯一的

对于每一列,您也遵循相同的逻辑。现在需要2个索引,而不是1个索引

entity
    .HasIndex(p => p.State)
    .IsUnique();

entity
    .HasIndex(p => p.Code)
    .IsUnique();
正如您在SQL Management Studio上看到的,索引已经创建。

当然,我的脚本表不包括索引。我们不创建约束,而是创建索引,索引不包括在创建表脚本中。

使用流畅的语法:

公共类状态
{
公共int Id{get;set;}
公共字符串代码{get;set;}
公共字符串状态{get;set;}
}
公共类MyContext:DbContext
{
配置时受保护的覆盖无效(DBContextOptions Builder Options Builder)
{
基本配置(选项生成器);
optionsBuilder.UseSqlServer(“***”);
}
模型创建时受保护的覆盖无效(ModelBuilder ModelBuilder)
{
//声明不可为空的列
modelBuilder.Entity().Property(s=>s.Code.IsRequired();
modelBuilder.Entity().Property(s=>s.State.IsRequired();
//添加唯一性约束
modelBuilder.Entity().HasIndex(s=>s.Code).IsUnique();
modelBuilder.Entity().HasIndex(s=>s.State).IsUnique();
}
}
生成的迁移代码:

protected override void Up(MigrationBuilder MigrationBuilder)
{
migrationBuilder.CreateTable(
名称:“国家”,
列:表=>new
{
Id=table.Column(可空:false)
.Annotation(“SqlServer:Identity”、“1,1”),
代码=table.Column(可空:false),
State=table.Column(可空:false)
},
约束:表=>
{
表.PrimaryKey(“PK_状态”,x=>x.Id);
});
migrationBuilder.CreateIndex(
名称:“IX_状态_代码”,
表:“国家”,
栏目:“代码”,
独特:正确);
migrationBuilder.CreateIndex(
名称:“九州”,
表:“国家”,
专栏:“国家”,
独特:正确);
}
以及SQL Server查询:

创建表[状态](
[Id]int不是空标识,
[代码]nvarchar(最大值)不为空,
[状态]nvarchar(450)不为空,
约束[PK_States]主键([Id])
);
在[States]([State])上创建唯一索引[IX_States\u State];
在[States]([Code])上创建唯一索引[IX_States_Code];

您希望状态和代码是唯一的,还是只希望代码是唯一的?我希望状态和代码都是唯一的。谢谢您的回答,但我已经尝试过了,但它不起作用。使用
requiredAttribute
时,您的列
state
code
可以为空?@或者不可以。这实际上是一个旧的迁移。我没有重新应用迁移的错误。