Entity Framework and ordered indexes

5/8/2023
3 minute read

In Entity Framework 7, the team has added support for ordered indexes to the fluent API. In this blog post we will look at how to use this feature and what it means for your database.

Ordered Index

Before we look at how to use this feature, let's first look at what it means for your database. An ordered index is an index that is created on a column or set of columns that are also used as the sort order for the data in the table. This means that the data in the table is stored in the order of the index. This can be useful for queries that sort the data in a particular order. For example, if you have a table of blog posts and you want to query the posts in order of the date they were posted, you can create an ordered index on the UpdatedDate column. This will ensure that the data is stored in the order of the UpdatedDate column.

The main benefits of an ordered index:

  1. Query optimization: When the order direction in the index matches the sorting direction specified in the query (using ORDER BY), the database engine can utilize the index to efficiently sort the results. This can significantly improve query performance by reducing the need for additional sorting operations.
  2. Range scans: An ordered index can help optimize range scans when the query involves conditions on the indexed columns. The database engine can quickly navigate to the start of the range and scan only the relevant rows in the desired order.
  3. Covering index: If the query involves filtering and sorting on multiple columns, having a composite index with a specific order direction for each column can make the index "covering." A covering index includes all the columns needed for the query, so the database engine does not need to perform additional work to retrieve data from the table. This can further improve query performance.

A word of caution here: Indexes are very nice and can help us a lot. However, they come at a cost. The more indexes you have, the more space they take up in your database. This can have a negative impact on performance. So, you should only add indexes when you need them. If you don't need them, don't add them. If you do need them, make sure you understand the trade-offs.

Entity Framework Support

For example, this very blog uses such an index. The main page shows all published blog posts order by the latest update date. So a query to the database looks like this (oversimplified):

SELECT * FROM [dbo].[BlogPosts]
WHERE [IsPublished] = 1
ORDER BY [UpdatedDate] DESC

To use the index in Entity Framework, we can use the following code:

public class BlogPostConfiguration : IEntityTypeConfiguration<BlogPost>
{
    public void Configure(EntityTypeBuilder<BlogPost> builder)
    {
        // ... Other configurations ...

        builder.HasIndex(x => new { x.IsPublished, x.UpdatedDate })
            .HasDatabaseName("IX_BlogPosts_IsPublished_UpdatedDate")
            .IsDescending(false, true);
    }
}

The IsDescending method is used to specify the order direction for each column in the index. The order direction can be either true for descending or false for ascending. This will create an index that looks like this:

CREATE NONCLUSTERED INDEX [IX_BlogPosts_IsPublished_UpdatedDate]
ON [dbo].[BlogPosts] ([IsPublished] ASC, [UpdatedDate] DESC)

The example is taken from a SQL Server - it might look a bit different on other databases.

Conclusion

Entity Framework 7 now supports ordered indexes. This can be useful for queries that sort the data in a particular order. For example, if you have a table of blog posts and you want to query the posts in order of the date they were posted. It can help you optimize your queries and improve performance. However, you should only add indexes when you need them.

Entity Framework - Storing complex objects as JSON

From time to time, it is nice to store complex objects or lists as JSON in the database. With Entity Framework 8, this is now easily possible. But this was possible all along with Entity Framework 7.

Entity Framework 8: Raw SQL queries on unmapped types

The next iteration of Entity Framework, namely Entity Framework 8, will have a new and exciting feature:

Support raw SQL queries without defining an entity type for the result

That means less boilerplate code!

Native DateOnly and TimeOnly support in Entity Framework 8 in SQL Server

.NET 6 brought us two new datatypes: DateOnly and TimeOnly. For those types we don't have any first class support in Entity Framework - until now.

There is a recent change, that hit us with Entity Framework 8 that might ease the situation and brings native support for those types.

An error has occurred. This application may no longer respond until reloaded. Reload x