【问题标题】:How can I collect the current SQL Server Session ID from an Entity Framework DbContext?如何从实体框架 DbContext 收集当前的 SQL Server 会话 ID?
【发布时间】: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();
}

【问题讨论】:

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


    【解决方案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 将在这些触发器执行时存储错误的用户/设备信息。
    猜你喜欢
    • 2017-06-29
    • 2014-08-12
    • 1970-01-01
    • 2018-06-01
    • 1970-01-01
    • 1970-01-01
    • 2017-05-14
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多