EF Core:在同一列上创建多个筛选索引

3
有什么原因导致EF Core不允许在同一列上创建多个索引?
    builder
      .ForSqlServerHasIndex(x => x.ColumnX)
      .ForSqlServerInclude(nameof(TableA.ColumnA), nameof(TableA.ColumnB))
      .HasFilter($"{nameof(TableA.ColumnX)} = 1 AND {nameof(TableA.IsDeleted)} = 0")
      .HasName($"IX_{nameof(TableA)}_{nameof(TableA.ColumnX)}_Filter_1}");

    builder
      .ForSqlServerHasIndex(x => x.ColumnX)
      .ForSqlServerInclude(nameof(TableA.ColumnA), nameof(TableA.ColumnB))
      .HasFilter($"{nameof(TableA.ColumnX)} = 0 AND {nameof(TableA.IsDeleted)} = 0")
      .HasName($"IX_{nameof(TableA)}_{nameof(TableA.ColumnX)}_Filter_0}");

以下是我尝试做的示例。EF Core不会生成两个索引,而是仅为第一次出现生成一个索引。然后,我必须手动编辑迁移脚本以获取第二个索引。
并不像SQL会抱怨那样?
1个回答

2
我有一个和你类似的需求——在同一属性上创建两个索引,但过滤条件不同。我刚刚发现 Entity Framework Core 将索引属性作为索引的标识符,这在文档中有所确认:
“EF Core 每个不同属性集只支持一个索引。如果您使用 Fluent API 在已有索引定义的属性集上配置索引(无论是约定还是以前的配置),则会更改该索引的定义。如果要进一步配置由约定创建的索引,则此操作很有用。”
手动将第一个索引添加回模型快照、迁移和迁移的快照可以绕过此行为。这是我们采取的方法,一切都按预期工作。但是,每次生成后续迁移时,它都会删除第一个索引,我们必须手动将其添加回去。如果我们能够使用名称作为索引的唯一标识符而不是使用索引属性列表,那就太好了。
另外,在您发布的示例中,您可以使用 IN() 运算符并创建以下单个索引来覆盖两种情况:
builder
    .ForSqlServerHasIndex(x => x.ColumnX)
    .ForSqlServerInclude(nameof(TableA.ColumnA), nameof(TableA.ColumnB))
    .HasFilter($"{nameof(TableA.ColumnX)} IN (1, 2) AND {nameof(TableA.IsDeleted)} = 0");

更新-2021年11月17日

此问题已在EntityFramework 5.0中得到解决。根据文档

现在可以在同一组属性上使用多个索引。这些索引现在通过模型中的名称进行区分。按照惯例,模型名称用作数据库名称;但是也可以使用HasDatabaseName独立配置。


我遇到了同样的问题,但是似乎在 OnModelCreating() 中重新排列我的过滤索引,使其在非过滤索引之后,问题得以解决。也许他们在 EFCore 5 中修复了这个问题? - Pieter-Jan Briers

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接