如何从实体框架DbContext收集当前的SQL Server会话ID?

时间:2014-02-19 17:12:16

标签: c# sql sql-server entity-framework entity-framework-5

有没有办法确定打开的@@SPID的当前SQL Server会话ID(DbContext),而不是直接对数据库进行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 个答案:

答案 0 :(得分:1)

首先,单独使用Dbcontext将打开数据库上的任何sql进程。查询

所以在这种情况下,当您运行SELECT @@SPID时,您肯定会打开一个带有新ID的新流程。

好消息是Entityframework将使用相同的过程来运行您的后续查询。因此,理想情况下,在相同的使用块中,您将始终获得相同的@@ SPID值。

您可以运行此查询

select *
from    master.dbo.sysprocesses
where program_name = 'EntityFramework' 

观察与Entity Framework关联的数据库上的当前进程。

然后,您可以使用下面的查询来获取与特定进程关联的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)