I have a WCF Data Service and I intend to use some session-based table functions (that creates temporary tables that are usable in the current session) upon insert or update.
I tried to use the SaveChanges method like this:
public partial class MyContext: DbContext
{
public override int SaveChanges()
{
var res = SetValues(true);
var s = Database.SqlQuery<string>("SELECT [Key] FROM TempContextView").ToList();
System.IO.File.AppendAllText(@"c:\Temp\session.txt", $"SIZE S: {s.Count}, script res: {res}");
foreach (var element in s)
{
System.IO.File.AppendAllText(@"c:\Temp\session.txt", $"RES: {element}"); //never reached
}
return base.SaveChanges();
}
public int SetValues(bool insert)
{
System.IO.File.AppendAllText(@"c:\Temp\session.txt", "SetV: " + insert);
return Database.ExecuteSqlCommand(insert ? "INSERT INTO TempContextView ([Key],[Value]) VALUES('Flag', '1')" : "DELETE FROM TempContextView WHERE[Key] = 'Flag'");
}
}
The TempContextView is a view that provides a temporary table created by a function:
SELECT TOP (32) [Key], Value
FROM Schema1.getContextTable()
ORDER BY [Key]
function [Schema1].[getContextTable]()
RETURNS @Context TABLE([Key] varchar(126), [Value] varchar(126))
WITH SCHEMABINDING
as...
However, when I select the values from the table that is created by the function, it returns nothing (the query size is 0, yet the insert returns 1).
Does it mean, I can't use EF with sessions? Or every EF function uses its own context? As the session table is used by other triggers, I need to have the proper key value.
What should I do about this? Any hint if EF is able to use these type of functionality?
UPDATE:
I have learned that EF uses exec sp_reset_connection before each executed command, and it resets all the temporary variables and tables.
So I tried to create a transaction to force EF to execute the commands in one session:
using (var scope = new TransactionScope(TransactionScopeOption.RequiresNew))
{
Database.ExecuteSqlCommand("INSERT INTO TempContextView ([Key],[Value]) VALUES('Flag', '1')"); //session #1?
base.SaveChanges(); //session #2? :(
scope.Complete();
}
It still creates new sessions, so I can't really merge the two commands.
Any suggestions?

EF will open and close the
SqlConnectionfor every command (causing connection resets), unlessDbContextconstructor,DbContext.Database.Connection.Open(), orEdit:
Looks like
TransactionScopedoes not suppress the connection reset when the connection is checked out of the segregated connection pool. So withTransactionScopeyou would still have to explicitly open theDbContext.Database.Connectionto use session state between commands.But
DbContext.Database.BeginTransaction()works (probably by preventing connection pooling for the life of theDbContext).Here's a complete working example using
sp_set_sesson_context: