Are EF Core 3.1 ExecuteSqlRaw / ExecuteSqlRawAsync drop-in replacements for ExecuteSqlCommand / ExecuteSqlCommandAsync?

The rule is simple.

EF Core 2.x has 3 ExecuteSqlCommand overloads:

public static int ExecuteSqlCommand(this DatabaseFacade databaseFacade,
    RawSqlString sql, params object[] parameters); // 1
public static int ExecuteSqlCommand(this DatabaseFacade databaseFacade,
   RawSqlString sql, IEnumerable<object> parameters); // 2
public static int ExecuteSqlCommand(this DatabaseFacade databaseFacade,
    FormattableString sql); // 3

which in EF Core 3.x are mapped to

public static int ExecuteSqlRaw(this DatabaseFacade databaseFacade,
    string sql, params object[] parameters); // 1
public static int ExecuteSqlRaw(this DatabaseFacade databaseFacade,
    string sql, IEnumerable<object> parameters); // 2
public static int ExecuteSqlInterpolated(this DatabaseFacade databaseFacade,
    FormattableString sql); // 3

Functionally they are fully equivalent. Raw overloads supports the same placeholders and parameter values (both named and unnamed) as v2.x overloads #1 and #2. And Interpolated has the exact same behavior as the v2.x overload #3.

The reason for renaming the method and using different names for interpolated and non interpolated sql parameter is the C# compile time overload resolution for v2.x overloads #1 and #3. Sometimes it chooses interpolated when the intent was to use the other one, and vise versa. Having separate names makes intent clear.

You can read more about the reasoning in EF Core 3.0 Breaking Changes – FromSql, ExecuteSql, and ExecuteSqlAsync have been renamed.

The information about supported parameter placeholders,names and values can be found in Raw SQL queries – Passing parameters.

But to answer your concrete question, if the existing v2.x code is

context.Database.ExecuteSqlCommand("DELETE FROM Table WHERE ID = @p0", id);

then change it to ExecuteSqlRaw.

And if was

context.Database.ExecuteSqlCommand($"DELETE FROM Table WHERE ID = {id}");

then change it to ExecuteSqlInterpolated.

Leave a Comment

Hata!: SQLSTATE[HY000] [1045] Access denied for user 'divattrend_liink'@'localhost' (using password: YES)