Can I fire an event on connect database in Entity Framework Core?

前端 未结 2 1437
执笔经年
执笔经年 2021-01-14 03:41

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

相关标签:
2条回答
  • 2021-01-14 03:57

    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);
    
    0 讨论(0)
  • 2021-01-14 04:18

    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()));
    
    0 讨论(0)
提交回复
热议问题