首页 > 解决方案 > 每次检索存储的 OutOfProc 的 HttpContext.Current.Session 对象都会调用数据库吗?

问题描述

我们的 MVC Web 应用程序是负载平衡的,并利用会话将数据持久化到 SQL 服务器中的 proc 之外。Web 配置设置如下:

<sessionState mode="SQLServer" allowCustomSqlDatabase="true" sqlConnectionString="Data Source..."/>

使用依赖注入,我们将一个包装我们会话的类传递给各种控制器

public class MyWebSession : IWebSession
{
    private const MyModelKey = "MyModelKey"
    public MyModel MyModel
    {
        get { return (MyModel ) HttpContext.Current.Session[MyModelKey]; }
        set { HttpContext.Current.Session[MyModelKey] = value; }
    }
}

我的问题是,如果在我们的控制器中我们做这样的事情:

var id = MyWebSession.MyModel.Id;
var description = MyModel.Id.Description;

这会导致多次访问数据库吗?还是在发出 http 请求时已经发生了这种命中,我可以将会话数据视为内存变量?

标签: c#asp.net

解决方案


Current指的是ContextBase,后者指的是HostContext,它看起来像这样:

    public static Object HostContext
    {
        [System.Security.SecurityCritical]  // auto-generated
        get
        {
            ExecutionContext.Reader ec = Thread.CurrentThread.GetExecutionContextReader();

            Object hC = ec.IllogicalCallContext.HostContext;
            if (hC == null)
                hC = ec.LogicalCallContext.HostContext;
            return hC;
        }

IllogicalCallContext 看起来像这样

internal class IllogicalCallContext
{
    private Hashtable m_Datastore;
    private Object m_HostContext;

    internal struct Reader
    {
        IllogicalCallContext m_ctx;

        public Reader(IllogicalCallContext ctx) { m_ctx = ctx; }

        public bool IsNull { get { return m_ctx == null; } }

        [System.Security.SecurityCritical]
        public Object GetData(String name) { return IsNull ? null : m_ctx.GetData(name); }

        public Object HostContext { get { return IsNull ? null : m_ctx.HostContext; } }
    }

    private Hashtable Datastore
    {
        get 
        { 
            if (null == m_Datastore)
            {
                // The local store has not yet been created for this thread.
                m_Datastore = new Hashtable();
            }
            return m_Datastore;
        }
    }

    internal Object HostContext
    {
        get
        {
            return m_HostContext;
        }
        set
        {
            m_HostContext = value;
        }
    }

        public Object HostContext { get { return IsNull ? null : m_ctx.HostContext; } }
    }

..ETC。

最终你结束了CallContext.HostContext看起来像这样

    internal Object HostContext
    {
        get
        {
            return m_HostContext;
        }
        set
        {
            m_HostContext = value;
        }
    }

因此,无论发生什么行为都将取决于某人在该HostContext属性中放置了什么。这是参考源结束的地方,因此可能有人或某物正在将字典或缓存对象放在那里,尽管我想它可能是数据库端点。

顺便说一句,这个迷宫中的某个地方应该是一个SessionState看起来像这样的对象:

https://github.com/microsoft/referencesource/blob/master/System.Web/State/SessionState.cs


推荐阅读