Search code examples
c#postgresqldbcontextrawsql

EF Core 3.1, how to use raw sql on a database with PostgreSQL (npgsql) or any other than SQL Server


For the code

public object GetRawSqlResult(string request)
{
    object result = ctx.Database.ExecuteSqlCommand(request);
    return result;
}

I get this error for ExecuteSqlCommand:

CS1061: 'DatabaseFacade' does not contain a definition for 'ExecuteSqlCommand' and no accessible extension method 'ExecuteSqlCommand' accepting a first argument of type 'DatabaseFacade' could be found (are you missing a using directive or an assembly type reference?)

There is a Database property in the Context class, but it does not give access to a direct SQL raw query (i.e., Context.Database).

The Microsoft help, Raw SQL Queries, does not tell how to do it without using a specific Context class.

I want a pure SQL command, and I do not want to pass through an entity. In hands, I only have the class name and want to verify the table exists into the database. I do not have any instance of it. There should be a way to just run a command against the database.

Enter image description here

Just for additional information (there is no "ExecuteSqlCommand..."):

Enter image description here


Solution

  • The actual documentation is always at learn.microsoft.com. In Entity Framework Core 3.1, the raw SQL commands are ExecuteSqlRaw and ExecuteSqlInterpolated. ExecuteSqlCommand is marked obsolete which is why it doesn't appear in the Intellisense popup. All those methods are DbContext extensions and have nothing to do with SQL Server. The methods that expect parameters expect a DbParameter-derived object, not specifically SqlParameter. You shouldn't have any problem using NpgsqlParameter.

    In many cases you'll be able to pass parameter values as extra parameters though. For example:

    using Microsoft.EntityFrameworkCore;
    ...
    
    var id = 8;
    var alwaysMinusOne = ctx.Database.ExecuteSqlRaw(
        @"SELECT * FROM ""Blogs"" WHERE ""Id"" = {0}",
        id);
    

    or

    var id = 8;
    var alwaysMinusOne = ctx.Database.ExecuteSqlInterpolated(
                             $@"SELECT * FROM ""Blogs"" WHERE ""Id"" = {id}");