By session i mean Postgres session (same TCP connection).
My question related to https://stackoverflow.com/a/19410907/1251169
I need to pass user id to Postgres trigger. From my research i can only see a way in using set session custom.userid = 'NAME'
(look at url above)
But it works only if i pass the query in the same session obviously. For example, this works
using (var context = new MyDbContext())
{
context.Database.ExecuteSqlCommand("set session custom.userid = 'NAME';
insert into my_table values ('abc', 1)");
}
Inside the my_table trigger i can read
select current_setting('custom.userid'); // NAME
This doesn't work:
using (var context = new MyDbContext())
{
context.Database.ExecuteSqlCommand("set session custom.userid = 'NAME';");
context.Database.ExecuteSqlCommand("insert into my_table values ('abc', 1)");
}
Because these are two different sessions.
select current_setting('custom.userid'); // empty string
I use EF Code First and manipulate models, not raw queries
using (var context = new MyDbContext())
{
context.Database.ExecuteSqlCommand("set session custom.userid = 'NAME';");
context.MyTables.Add(new MyTable
{
Code = 'abc',
Value = 1
});
context.SaveChanges();
}
This doesn't work either, because there are 2 different sessions. As far as I understand, EF creates raw SQL query inside its internals and it is executed in separate session.
Is it possible to access these internals (write hook function or somehow) to add "set session" query to any query issued by EF?
p.s.
A possible solution is to use set local
(not session) and create additional transaction (if not exist). But i'd like to avoid create transaction just to pass some data.
public class MyDbContext : DbContext
{
public override int SaveChanges()
{
IDbContextTransaction trans = null;
try
{
if (Database.CurrentTransaction == null)
{
trans = Database.BeginTransaction();
}
Database.ExecuteSqlCommand("set LOCAL custom.userid = 'test987';");
return base.SaveChanges();
}
finally
{
trans?.Commit();
}
}
}