FormattableStringFactory - Creating dynamic FormattableString instances

8/19/2024
2 minute read

I recently came across the FormattableStringFactory to create dynamic FormattableString instances. This is a very useful feature in combination with safe SQL queries and the SqlQuery method of Entity Framework Core.

SqlQuery method

Short recap: The SqlQuery method of Entity Framework Core allows you to execute raw SQL queries and map the results to entities. This is useful if you want to execute complex queries that are not possible with LINQ.

var ids = await context.Database
    .SqlQuery<int>($"SELECT [BlogId] FROM [Blogs]")
    .ToListAsync();

It wants a FormattableString as input so it can safely interpolate the values into the SQL query and prevent SQL injection attacks. The "problem" is that you can't concatenate FormattableString instances directly. I needed this for a dynamic SQL query. Imagine in the given example above sometimes you want to filter for specific ID's from a given list.

var ids = GetIds();
// If ids is empty, the SQL query isn't valid
var query = $"SELECT [BlogId] FROM [Blogs] WHERE [BlogId] IN ({string.Join(", ", ids)})";

FormattableStringFactory

But we can utilize the FormattableStringFactory to create dynamic FormattableString instances from a given string!

var ids = GetIds();

var stringBuilder = new StringBuilder("SELECT [BlogId] FROM [Blogs]");
if (ids.Any())
{
    stringBuilder.Append(" WHERE [BlogId] IN ({0})", string.Join(", ", ids));
}

var query = FormattableStringFactory.Create(stringBuilder.ToString());
var result = await context.Database
    .SqlQuery<int>(query)
    .ToListAsync();

If your FormattableString contains placeholders, you can pass them in like this:

var query = "Hello {0}!";
var formattableString = FormattableStringFactory.Create(query, "World");

These two mechanisms combined allow you to create dynamic SQL queries with Entity Framework Core in a safe way.

EF Core 6 - New Features

EF Core 6 is right in front of our door and it looks very promising. In this blog post I will show what new features are to come.

Are my EF LINQ to SQL queries safe?

Have you ever asked yourself if your EF LINQ queries are susceptible to SQL injection attacks? Either because you are querying some user data from a text field or directly taking whatever your API hits against the database?

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!

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