如何从实体框架 DbContext 收集当前的 SQL Server 会话 ID?
Posted
技术标签:
【中文标题】如何从实体框架 DbContext 收集当前的 SQL Server 会话 ID?【英文标题】:How can I collect the current SQL Server Session ID from an Entity Framework DbContext? 【发布时间】:2014-02-19 17:12:15 【问题描述】:有没有办法确定打开的DbContext
的当前 SQL Server 会话 ID (@@SPID
),而不是直接对数据库进行 SQL 查询?
如果有,是否保证 SQL Server 会话 ID 将保持不变,直到释放 DbContext
并将其连接释放回实体框架连接池?类似的东西:
using (MyEntities db = new MyEntities())
// the following 3 pieces of code are not existing properties and will result in compilation errors
// I'm just looking for something similar to the following 3 lines
db.CurrentSessionId; //error
db.Database.CurrentSessionId; //error
((IObjectContextAdapter)db).ObjectContext.Connection.CurrentSessionId; //error
// the following code will work, but will this session id be the same until the original DbContext is disposed?
// is there any chance that a db.Database.SqlQuery call will spin off it's own connection from the pool?
short spid = db.Database.SqlQuery<short>("SELECT @@SPID").FirstOrDefault();
【问题讨论】:
【参考方案1】:首先,单独的 Dbcontext 将不会打开数据库上的任何 sql 进程。查询确实。
所以在这种情况下,当您运行 SELECT @@SPID
时,您肯定会打开一个具有新 ID 的新进程。
好消息是 Entityframework 将使用相同的过程来运行您的后续查询。所以理想情况下,在同一个 using 块中,您将始终获得相同的 @@SPID 值。
你可以运行这个查询
select *
from master.dbo.sysprocesses
where program_name = 'EntityFramework'
观察与实体框架关联的数据库上的当前进程。
然后您可以使用下面的查询来获取与特定进程关联的 SQL 语句。有关更多信息,请在此处查看接受的答案:List the queries running on SQL Server
declare
@spid int
, @stmt_start int
, @stmt_end int
, @sql_handle binary(20)
set @spid = XXX -- Fill this in
select top 1
@sql_handle = sql_handle
, @stmt_start = case stmt_start when 0 then 0 else stmt_start / 2 end
, @stmt_end = case stmt_end when -1 then -1 else stmt_end / 2 end
from master.dbo.sysprocesses
where spid = @spid
order by ecid
SELECT
SUBSTRING( text,
COALESCE(NULLIF(@stmt_start, 0), 1),
CASE @stmt_end
WHEN -1
THEN DATALENGTH(text)
ELSE
(@stmt_end - @stmt_start)
END
)
FROM ::fn_get_sql(@sql_handle)
【讨论】:
有趣。我仍在尝试围绕 Entity Framework 如何处理连接池。我的问题源于这样一个事实,即我将来自 webapi 请求的用户/设备信息存储在以@@spid 作为主键的表中,然后通过 EntityFramework 在另一个表上进行二次更改。目标是在该表上获得触发器以通过当前@@spid 选择用户/设备并存储有关更改的审计信息。我们发现大约 1/50,000 次,@@spid 将在这些触发器执行时存储错误的用户/设备信息。以上是关于如何从实体框架 DbContext 收集当前的 SQL Server 会话 ID?的主要内容,如果未能解决你的问题,请参考以下文章
如何从DbContext中清除未插入的POCO? - 实体框架代码优先