Entity Framework Core 2 – Explicit compiled queries

 

Entity Framework Core 2 was released on August 14th. It brought new features.

On this article I will explain one of them: Explicitly compiled queries

Entity Framework Core included query caching since version 1, but there is still some overhead associated with calculating the key from the query and getting it from the cache. Therefore, version 2 introduced a capability that existed in LINQ to SQL and Entity Framework 5: explicit query compilation and execution. By this, we are able to pre-compile a query and use it in whatever context we want (of a compatible type, of course). We can even eagerly fetch associated collections or entities.

Example:

private static Func<AdventureWorksContextDI, int, Orders> _getOrderById =
  EF.CompileQuery((AdventureWorksContextDI context, int id) =>
  context.WorkOrders.Select(
  x => new Orders
  {
     Id = x.WorkOrderId,
     ProductName = x.Product.Name,
     Quantity = x.OrderQty,
     Date = x.DueDate
  }).FirstOrDefault(x => x.Id == id));

Usage:

public Orders GetOrderByIdCompiled(int id)
{
   return _getOrderById(_context, id);
}

What performance improvments to expect ?

I executed the non compiled query and the same version but compiled (using Stopwatch object), and I measured this:

  • Compiled query: 2 to 15 ms
  • Non compiled query: 4 to 23 ms

 

It looks faster 🙂

Entity Framework Core 2 – DbContext Pools

 

Entity Framework Core 2 was released on August 14th. It brought new features.

On this article I will explain one of them: DbContext Pools

Normally when a DbContext is injected somewhere by the dependency injection framework, a new instance is created every time. With this, we can have a pool of instances, 128 by default. It is a performance improvement and it is configured like this (console app example):

var serviceProvider = new ServiceCollection()
 .AddDbContextPool<AdventureWorksContext>(options => { //options })
 .AddScoped<IEfQueries, EfQueries>()
 .BuildServiceProvider();

.AddDbContext from Entity Framework Core 1 is still implemeted in Entity Framework Core 2.

What kind of improvment to expect ?

Let’s build a Query and let’s see the improvment by using 2 instances of the queries service intantiated by injection dependency system:

public Orders GetOrderById(int id)
{
   return _context.WorkOrders.Select(
                             x => new Orders
                             {
                                Id = x.WorkOrderId,
                                ProductName = x.Product.Name,
                                Quantity = x.OrderQty,
                                Date = x.DueDate
                             }).FirstOrDefault(x => x.Id == id);
}

 

// Using AddDbContext 
var efqueriesService1 = serviceProvider.GetService<IEfQueries>();
efqueriesService1.GetOrders();
var efqueriesService2 = serviceProvider.GetService<IEfQueries>();
efqueriesService2.GetOrders();

// Using AddDbContextPool
var efqueriesService1 = serviceProvider.GetService<IEfQueries>();
efqueriesService1.GetOrders();
var efqueriesService2 = serviceProvider.GetService<IEfQueries>();
efqueriesService2.GetOrders();

I executed this serie of execution 20 times and I measured the execution (using Stopwatch object) this:

With AddDbContext:

  • Instance 1: 23 to 29 ms (instantiation + execution)
  • Instance 2: 7 to 9 ms (instantiation + execution)

With AddDbContextPool:

  • Instance 1: 17 to 21 ms (instantiation + execution)
  • Instance 2: 5 to 7 ms (instantiation + execution)

It looks a bit more performant! 😉

Entity Framework Core 2 – Pluralization and Singularization

 

Entity Framework Core 2 was released on August 14th. It brought new features.

On this article I will explain one of them : Pluralization and Singularization

There is a new IPluralizer interface. It can be used to pluralize table names when EF is generating the database (dotnet ef database update) or entities when generating classes from it (Scaffold-DbContext). The way to use it is somewhat tricky, as we need to have a class implementing IDesignTimeServices, and this class will be discovered automatically by these tools.

In this example I provide a custom implementation with the Nuget package Inflector

Example:

public class CustomPluralizer : IPluralizer
{
   public string Pluralize(string name)
   {
      return Inflector.Inflector.Pluralize(name) ?? name;
   }
   public string Singularize(string name)
   {
      return Inflector.Inflector.Singularize(name) ?? name;
   }
}
public class CustomDesignTimeServices : IDesignTimeServices
{
   public void ConfigureDesignTimeServices(IServiceCollection services)
   {
     services.AddSingleton<IPluralizer, CustomPluralizer>();
   }
}

That’s it 🙂