Anteckning
Åtkomst till den här sidan kräver auktorisering. Du kan prova att logga in eller ändra kataloger.
Åtkomst till den här sidan kräver auktorisering. Du kan prova att ändra kataloger.
Index är ett vanligt begrepp i många datalager. Implementeringen i datalagret kan variera, men de används för att göra sökningar baserade på en kolumn (eller uppsättning kolumner) mer effektiva. Mer information om bra indexanvändning finns i avsnittet index i prestandadokumentationen.
Du kan ange ett index över en kolumn på följande sätt:
[Index(nameof(Url))]
public class Blog
{
public int BlogId { get; set; }
public string Url { get; set; }
}
Anmärkning
Enligt konventionen skapas ett index i varje egenskap (eller uppsättning egenskaper) som används som en sekundärnyckel.
Sammansatt index
Ett index kan också sträcka sig över mer än en kolumn:
[Index(nameof(FirstName), nameof(LastName))]
public class Person
{
public int PersonId { get; set; }
public string FirstName { get; set; }
public string LastName { get; set; }
}
Index över flera kolumner, även kallade sammansatta index, påskyndar frågor som filtrerar på indexets kolumner, men även frågor som endast filtrerar på de första kolumnerna som omfattas av indexet. Mer information finns i prestandadokumenten .
Indexet är unikt
Index är som standard inte unika: flera rader får ha samma värde för indexets kolumnuppsättning. Du kan göra ett index unikt på följande sätt:
[Index(nameof(Url), IsUnique = true)]
public class Blog
{
public int BlogId { get; set; }
public string Url { get; set; }
}
Om du försöker infoga fler än en entitet med samma värden för indexets kolumnuppsättning genereras ett undantag.
Indexsorteringsordning
I de flesta databaser kan varje kolumn som omfattas av ett index antingen vara stigande eller fallande. För index som endast täcker en kolumn spelar detta vanligtvis ingen roll: databasen kan passera indexet i omvänd ordning efter behov. För sammansatta index kan beställningen dock vara avgörande för bra prestanda och kan innebära skillnaden mellan ett index som används av en fråga eller inte. I allmänhet bör indexkolumnernas sorteringsordningar motsvara de som anges i satsen i ORDER BY din fråga.
Indexsorteringsordningen är stigande som standard. Du kan göra så att alla kolumner har fallande ordning på följande sätt:
[Index(nameof(Url), nameof(Rating), AllDescending = true)]
public class Blog
{
public int BlogId { get; set; }
public string Url { get; set; }
public int Rating { get; set; }
}
Du kan också ange sorteringsordningen efter kolumn enligt följande:
[Index(nameof(Url), nameof(Rating), IsDescending = new[] { false, true })]
public class Blog
{
public int BlogId { get; set; }
public string Url { get; set; }
public int Rating { get; set; }
}
Indexnamngivning och flera index
Enligt konvention heter index som skapats i en relationsdatabas IX_<type name>_<property name>. För sammansatta index blir <property name> en lista med egenskapsnamn avgränsade med understreck.
Du kan ange namnet på indexet som skapades i databasen:
[Index(nameof(Url), Name = "Index_Url")]
public class Blog
{
public int BlogId { get; set; }
public string Url { get; set; }
}
Observera att om du anropar HasIndex fler än en gång på samma uppsättning egenskaper fortsätter det att konfigurera ett enda index i stället för att skapa ett nytt:
modelBuilder.Entity<Person>()
.HasIndex(p => new { p.FirstName, p.LastName })
.HasDatabaseName("IX_Names_Ascending");
modelBuilder.Entity<Person>()
.HasIndex(p => new { p.FirstName, p.LastName })
.HasDatabaseName("IX_Names_Descending")
.IsDescending();
Eftersom det andra HasIndex anropet åsidosätter det första skapar detta bara ett enda fallande index. Detta kan vara användbart för att ytterligare konfigurera ett index som har skapats av konventionen.
Om du vill skapa flera index över samma uppsättning egenskaper skickar du ett namn till HasIndex, som ska användas för att identifiera indexet i EF-modellen och för att skilja det från andra index över samma egenskaper:
modelBuilder.Entity<Person>()
.HasIndex(p => new { p.FirstName, p.LastName }, "IX_Names_Ascending");
modelBuilder.Entity<Person>()
.HasIndex(p => new { p.FirstName, p.LastName }, "IX_Names_Descending")
.IsDescending();
Observera att det här namnet också används som standard för databasnamnet, så explicit angivelse av HasDatabaseName krävs inte.
Indexfilter
Med vissa relationsdatabaser kan du ange ett filtrerat eller partiellt index. På så sätt kan du endast indexera en delmängd av en kolumns värden, minska indexets storlek och förbättra både prestanda- och diskutrymmesanvändningen. Mer information om SQL Server-filtrerade index finns i dokumentationen.
Du kan använda Fluent API för att ange ett filter för ett index, som tillhandahålls som ett SQL-uttryck:
protected override void OnModelCreating(ModelBuilder modelBuilder)
{
modelBuilder.Entity<Blog>()
.HasIndex(b => b.Url)
.HasFilter("[Url] IS NOT NULL");
}
När du använder SQL Server-providern lägger EF till ett 'IS NOT NULL' filter för alla nullbara kolumner som ingår i ett unikt index. Om du vill åsidosätta den här konventionen kan du ange ett null värde.
protected override void OnModelCreating(ModelBuilder modelBuilder)
{
modelBuilder.Entity<Blog>()
.HasIndex(b => b.Url)
.IsUnique()
.HasFilter(null);
}
Inkluderade kolumner
Med vissa relationsdatabaser kan du konfigurera en uppsättning kolumner som ingår i indexet, men som inte ingår i dess "nyckel". Detta kan avsevärt förbättra frågeprestanda när alla kolumner i frågan ingår i indexet, antingen som nyckelkolumner eller icke-nyckelkolumner, eftersom själva tabellen inte behöver nås. Mer information om SQL Server-inkluderade kolumner finns i dokumentationen.
I följande exempel Url är kolumnen en del av indexnyckeln, så alla frågefiltreringar i kolumnen kan använda indexet. Men dessutom behöver frågor som endast kommer åt kolumnerna Title och PublishedOn inte komma åt tabellen och köras mer effektivt:
protected override void OnModelCreating(ModelBuilder modelBuilder)
{
modelBuilder.Entity<Post>()
.HasIndex(p => p.Url)
.IncludeProperties(
p => new { p.Title, p.PublishedOn });
}
Kontrollera begränsningar
Kontrollbegränsningar är en standardrelationsfunktion som gör att du kan definiera ett villkor som måste gälla för alla rader i en tabell; Försök att infoga eller ändra data som bryter mot begränsningen misslyckas. Kontrollbegränsningar liknar icke-null-begränsningar (som förbjuder null-värden i en kolumn) eller unika begränsningar (som förbjuder dubbletter), men tillåter att godtyckliga SQL-uttryck definieras.
Du kan använda Api:et Fluent för att ange en kontrollbegränsning för en tabell, som tillhandahålls som ett SQL-uttryck:
protected override void OnModelCreating(ModelBuilder modelBuilder)
{
modelBuilder
.Entity<Product>()
.ToTable(b => b.HasCheckConstraint("CK_Prices", "[Price] > [DiscountedPrice]"));
}
Flera kontrollbegränsningar kan definieras i samma tabell, var och en med sitt eget namn.
Obs! Vissa vanliga kontrollbegränsningar kan konfigureras via community-paketet EFCore.CheckConstraints.