Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
777 views
in Technique[技术] by (71.8m points)

entity framework core - Many to Many index creation convention

My question is related to this SO post, but instead of preventing I want to understand what's the convention of creating an index, as I can't find anything.

Given entities:

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

And many to many relation setup:

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

The resulting migration has index on Entity2Id

// create table etc...

migrationBuilder.CreateIndex(
    name: "IX_Entity1Entity2Link_Entity2Id",
    table: "Entity1Entity2Link",
    column: "Entity2Id");

I'm looking to find what's the convention to create this index ? One convention I could find states:

EF Core will always create indexes for foreign key and alternate keys.

But then why I don't see another index on Entity1Id column ?

Also I noticed I can swap index created on a column, by swapping column in composite key definition, e.g.

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

This will create an index on Entity1Id column:

migrationBuilder.CreateIndex(
    name: "IX_Entity1Entity2Link_Entity1Id",
    table: "Entity1Entity2Link",
    column: "Entity1Id");

I'm using 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" />
See Question&Answers more detail:os

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Reply

0 votes
by (71.8m points)

It's basically what you referred to

By convention, an index is created in each property (or set of properties) that are used as a foreign key.

with one exception, partially covered by the following excerpt from Composite Index section:

Indexes over multiple columns, also known as composite indexes, speed up queries which filter on index's columns, but also queries which only filter on the first columns covered by the index.

So, indexes are created automatically by convention for all FKs, except if the FK properties are leading columns in some other composite index. Because leading columns of a composite index provide the same efficient search capability as separate index containing these columns, thus separate index is redundant, and EF Core is smart enough to not create it.

In your example, there is already composite index associated with the PK (Entity1Id, Entity2Id) columns, which covers Entity1Id FK, hence no additional index is created. If you swap the columns in the PK, then Entity2Id will be covered, so only additional index for Entity1Id FK will be created.


与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
OGeek|极客中国-欢迎来到极客的世界,一个免费开放的程序员编程交流平台!开放,进步,分享!让技术改变生活,让极客改变未来! Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...