I\'ve one DbContext with all working to access my Postgresql DB, but I need to run one little SQL command when connection session starts with DB. I need to do this for every
You should be able to do it by passing a connection into your DbContext
and hooking the StateChange
event: (Please forgive the SQLite example. I know you said PostgreSQL.)
var connection = new SqliteConnection(connectionString);
_connection.StateChange += (sender, e) =>
{
if (e.OriginalState != ConnectionState.Open)
return;
var senderConnection = (DbConnection)sender;
using (var command = senderConnection.CreateCommand())
{
command.Connection = senderConnection;
command.CommandText = "-- TODO: Put little SQL command here.";
command.ExecuteNonQuery();
}
};
optionsBuilder.UseSqlite(connection);
If you are using EF Core 3.0 or greater you can now use a DBConnectionInterceptor for this. The code to do what you want looks something like this.
public class DbUserIdProvider : DbConnectionInterceptor
{
// Called just after EF has called Open().
public override void ConnectionOpened(DbConnection connection, ConnectionEndEventData eventData)
{
base.ConnectionOpened(connection, eventData);
var cmd = connection.CreateCommand();
cmd.CommandText = "set session.client_user_id to 'myid'";
cmd.ExecuteNonQuery();
}
// Called just after EF has called OpenAsync().
public override Task ConnectionOpenedAsync(DbConnection connection, ConnectionEndEventData eventData, CancellationToken cancellationToken = default)
{
var cmd = connection.CreateCommand();
cmd.CommandText = "set session.client_user_id to 'myid'";
cmd.ExecuteNonQuery();
return base.ConnectionOpenedAsync(connection, eventData, cancellationToken);
}
}
ConnectionOpenedAsync() is called when you use an async method to access the database.
To wire in this interceptor so the context knows about it, you have to add it to the AddDbContext call in Startup.cs like this.
services.AddDbContext<ApplicationDbContext>(options => options
.UseNpgsql(connection)
.AddInterceptors(new DbUserIdProvider()));