Entity Framework - Setting session_context using IDbConnectionInterceptor

后端 未结 2 689
梦如初夏
梦如初夏 2021-02-10 00:46

I\'m following this tutorial in order to use Row Level security in SQL Server via Entity Framework 6 CodeFirst. The tutorial code sample shows how to use IDbConnectionIntercepto

相关标签:
2条回答
  • 2021-02-10 01:06

    You can use the Connection_StateChaned event of your DbContext if you are using EF like so.

     static void Main(string[] args)
        {               
            using (var db = new AdventureWorks2016CTP3Entities())
            {
                db.Database.Connection.StateChange += Connection_StateChange;
                db.Database.Log = (log) => System.Diagnostics.Debug.WriteLine(log);
    
                var purchase = db.SalesOrderHeader.Select(i => i.SalesPersonID);
    
                foreach (var m in purchase)
                {
                    Console.WriteLine(m);
                }
            }
    
        }
    
        private static void Connection_StateChange(object sender, System.Data.StateChangeEventArgs e)
        {
            if(e.CurrentState == System.Data.ConnectionState.Open)
            {
                var cmd = (sender as System.Data.SqlClient.SqlConnection).CreateCommand();
                cmd.CommandType = System.Data.CommandType.Text;
                cmd.CommandText = "exec sp_set_session_context 'UserId', N'290'";
    
                cmd.ExecuteNonQuery();
            }
        }
    
    0 讨论(0)
  • 2021-02-10 01:07

    I realize this is an older question, but figured I would post our solution for those looking for one. We are using interceptors to Inject a SQLServer session_context statement into the commands/connections running through EF.

    In our case, we had to create Interceptors for DbCommand and DbConnection to handle both EF Linq queries and raw SQL queries that run through Commands. These Interceptor classes implement IDbCommandInterceptor and IDbConnectionInterceptor respectively.

    For DbCommandInterceptor, we use the SqlCommand.CommandText to prepend our EXEC sp_set_session_context raw SQL to each command coming through the interceptor.

    public class SessionContextDbCommandInterceptor : IDbCommandInterceptor
    

    For DbConnectionInterceptor, we implement the Opened method and execute a SqlCommand against the connection that runs our sp_set_session_context SQL.

    public class SessionContextDbConnectionInterceptor : IDbConnectionInterceptor
    {
        public void Opened(DbConnection connection, DbConnectionInterceptionContext interceptionContext)
        {...}
    

    We then created a DbConfiguration class that adds the interceptors within the constructor:

    public class SessionContextConfiguration : DbConfiguration
    {
        public SessionContextConfiguration()
        {
            AddInterceptor(new SessionContextDbConnectionInterceptor());
            AddInterceptor(new SessionContextDbCommandInterceptor());
        }
    }
    

    Then add this DbConfiguration class to our DbContext class via the DbConfigurationType Attribute as well as to our web.config:

    [DbConfigurationType(typeof(SessionContextConfiguration))]
    public class MyContext : DbContext
    
    <entityFramework codeConfigurationType="MyAssembly.SessionContextConfiguration, MyAssembly">
    

    We inject our DbContexts using Autofac as we normally would and the interceptors are automatically added to the DbContext instances because of the Configuration class.

    0 讨论(0)
提交回复
热议问题