多对多索引创建约定

Mic*_*ael 8 entity-framework-core

我的问题与这篇 SO post相关,但我不想阻止,而是想了解创建索引的约定是什么,因为我找不到任何东西。

给定实体:

public class Entity1
{
  public Guid Id {get;set;}
  public string Name {get;set;}
  public ICollection<Entity1Entity2Link> Links {get;set;}
}

public class Entity2
{
  public Guid Id {get;set;}
  public string Name {get;set;}
  public ICollection<Entity1Entity2Link> Links {get;set;}
}

public class Entity1Entity2Link
{
  public Guid Entity1Id {get;set;}
  public Entity1 Entity1 {get;set;}

  public Guid Entity2Id {get;set;}
  public Entity2 Entity2 {get;set;}
}
Run Code Online (Sandbox Code Playgroud)

以及多对多关系设置:

modelBuilder
                .Entity<Entity1Entity2Link>()
                .HasKey(ofl => new
                {
                    ofl.Entity1Id ,
                    ofl.Entity2Id 
                });

            modelBuilder
                .Entity<Entity1Entity2Link>()
                .HasOne(ofl => ofl.Entity1)
                .WithMany(e => e.Links)
                .HasForeignKey(ofl => ofl.Entity1Id);

            modelBuilder
                .Entity<Entity1Entity2Link>()
                .HasOne(ofl => ofl.Entity2)
                .WithMany(e => e.Links)
                .HasForeignKey(ofl => ofl.Entity2Id);
Run Code Online (Sandbox Code Playgroud)

生成的迁移在 Entity2Id 上有索引

// create table etc...

migrationBuilder.CreateIndex(
    name: "IX_Entity1Entity2Link_Entity2Id",
    table: "Entity1Entity2Link",
    column: "Entity2Id");
Run Code Online (Sandbox Code Playgroud)

我正在寻找创建此索引的约定是什么?我能找到的一项公约规定:

EF Core 将始终为外键和备用键创建索引。

但为什么我在列上看不到另一个索引Entity1Id

我还注意到我可以通过交换复合键定义中的列来交换在列上创建的索引,例如

modelBuilder
    .Entity<Entity1Entity2Link>()
    .HasKey(ofl => new
    {
        ofl.Entity2Id,
        ofl.Entity1Id
    });
Run Code Online (Sandbox Code Playgroud)

这将在列上创建索引Entity1Id

migrationBuilder.CreateIndex(
    name: "IX_Entity1Entity2Link_Entity1Id",
    table: "Entity1Entity2Link",
    column: "Entity1Id");
Run Code Online (Sandbox Code Playgroud)

我正在使用 EF Core 3.1.2。

<PackageReference Include="Microsoft.EntityFrameworkCore" Version="3.1.2" />
<PackageReference Include="Microsoft.EntityFrameworkCore.Design" Version="3.1.2" />
<PackageReference Include="Microsoft.EntityFrameworkCore.SqlServer" Version="3.1.2" />
<PackageReference Include="Microsoft.EntityFrameworkCore.Tools" Version="3.1.2" />
Run Code Online (Sandbox Code Playgroud)

Iva*_*oev 8

基本上就是你提到的

按照约定,在用作外键的每个属性(或属性集)中创建索引。

除一个例外,以下综合指数部分摘录部分涵盖了该内容:

多列索引(也称为复合索引)不仅可以加快对索引列进行筛选的查询的速度,而且还可以加快仅对索引覆盖的第一列进行筛选的查询的速度。

因此,按照惯例,索引会自动为所有 FK 创建,除非FK 属性是某些其他复合索引中的前导列。由于复合索引的前导列提供与包含这些列的单独索引相同的高效搜索能力,因此单独索引是多余的,并且 EF Core 足够聪明,不会创建它。

在您的示例中,已经存在与 PK(Entity1Id, Entity2Id)列关联的复合索引,该索引覆盖了Entity1IdFK,因此不会创建其他索引。如果交换PK中的列,那么Entity2Id将被覆盖,因此只会为Entity1IdFK创建附加索引。


归档时间:

查看次数:

793 次

最近记录:

4 年,5 月 前