操作无效.连接已关闭.ASP.NET MVC

mar*_*123 4 asp.net asp.net-mvc linq-to-sql

它不会经常发生,但我会不时通过电子邮件向我发送一份异常报告,指向这段代码.我想知道你是否看到以下代码有任何问题.我不能让它在本地失败,并且使用断点跟踪数据总是一步一步地给出正确的结果.

namespace DomainModel.Concrete
{
public class ConfigRepository : IConfigRepository
{
    static mvCmsContext context { get; set; }
    public ConfigRepository() { context = new mvCmsContext(); }

    private static Func<mvCmsContext, string, Configuration> _byName =
        CompiledQuery.Compile((mvCmsContext context, string configName) =>
            (from c in context.Configs
             where c.configName == configName
             select c).SingleOrDefault());
    static public Configuration ByName(string configName)
    {
        var result = (Configuration)HttpContext.Current.Cache.Get(configName);
        if (result == null)
        {
            using (new mvCmsContext())
            {
                HttpContext.Current.Cache.Insert(configName, _byName(context, configName));
                result = (Configuration)HttpContext.Current.Cache.Get(configName);
            }
        }
        return result;
    }

}
}
Run Code Online (Sandbox Code Playgroud)

这是调用该方法的服务:

public class ConfigService
{
public static string siteName
{
    get { return ConfigRepository.ByName("Site_Name").configValue; }
}
public static string copyright
{
    get { return ConfigRepository.ByName("Copyright").configValue; }
}
public static string companyName
{
    get { return ConfigRepository.ByName("Company_Name").configValue; }
}
public static string homeTitle
{
    get { return ConfigRepository.ByName("Home_Title").configValue; }
}
public static string contactEmail
{
    get { return ConfigRepository.ByName("Contact_Email").configValue; }
}
public static string physicalAddress
{
    get { return ConfigRepository.ByName("Physical_Address").configValue; }
}
public static string phoneNumber
{
    get { return ConfigRepository.ByName("Phone_Number").configValue; }
}
}
Run Code Online (Sandbox Code Playgroud)

以下是收到的报告:

**摘要**---------------此消息包含为此通知安排的总共1个事件中的事件1到1.在此通知开始时缓冲区中剩余0个事件.

**应用程序信息**---------------应用程序域:/ LM/W3SVC/66/ROOT-7-129384226573152341信任级别:完整应用程序虚拟路径:/应用程序路径:D:*****.com \机器名称:WIN11

**事件**---------------事件代码:3005事件消息:发生了未处理的异常.活动时间:1/2/2011 12:17:44 AM活动时间(UTC):1/2/2011 6:17:44 AM活动编号:f909c5c676bd4ca1ba21512c678ac502活动顺序:6活动现场:1活动详情代码:0

进程信息:进程ID:26904进程名称:w3wp.exe帐户名:NT AUTHORITY\NETWORK SERVICE

异常信息:异常类型:System.InvalidOperationException异常消息:无效的操作.连接已关闭.

请求信息:请求URL:http:// .com/article / -ALERT请求路径:/ article/III-ALERT用户主机地址:68.230.129.53用户:已通过身份验证:False身份验证类型:线程帐户名称:NT AUTHORITY\NETWORK服务

线程信息:线程ID:6线程帐户名称:NT AUTHORITY\NETWORK SERVICE模拟:False堆栈跟踪:位于System的System.Data.SqlClient.SqlConnection.get_HasLocalTransactionFromAPI()处的System.Data.SqlClient.SqlConnection.GetOpenConnection()处. System.Data.SqlClient.SqlCommand.RunExecuteReader中System.Data.SqlClient.SqlCommand.RunExecuteReader(CommandBehavior cmdBehavior,RunBehavior runBehavior,Boolean returnStream,String方法,DbAsyncResult结果)中的Data.SqlClient.SqlCommand.ValidateCommand(String method,Boolean async) SystemB数据处理
System.Data.SqlClient.SqlCommand.ExecuteDbDataReader(CommandBehavior行为)的System.Data.SqlClient.SqlCommand.ExecuteReader(CommandBehavior behavior,String方法)中的(CommandBehavior cmdBehavior,RunBehavior runBehavior,Boolean returnStream,String方法).SqlClient.SqlProvider.Execute(表达式查询,QueryInfo queryInfo,IObjectReaderFactory工厂,Object [] parentArgs,Object [] userArgs,ICompiledSubQuery [] subQu 在System.Data.Linq.SqlClient.SqlProvider的System.Data.Linq.SqlClient.SqlProvider.ExecuteAll(Expression query,QueryInfo [] queryInfos,IObjectReaderFactory factory,Object [] userArguments,ICompiledSubQuery [] subQueries)处的eries,Object lastResult. System.Data.Linq.CompiledQuery.Invoke的System.Data.Linq.CompiledQuery.ExecuteQuery(DataContext context,Object [] args)中的CompiledQuery.Execute(IProvider提供程序,Object []参数)[TArg0,TArg1,TResult](TArg0 arg0,TArg1 arg1)在DomainModel.Concrete.ConfigRepository.ByName(String configName)的DomainModel.Services.ConfigService.get_companyName()at ASP.views_shared_site_master._ Render _control1(HtmlTextWriter __w,Control parameterContainer)at System.Web.UI.Control System.Web.Mvc.ViewPage.Render上System.Web.UI.Page.Render(HtmlTextWriter writer)的System.Web.UI.Control.RenderChildrenInternal(HtmlTextWriter writer,ICollection children)中的.RenderChildrenInternal(HtmlTextWriter writer,ICollection children) (HtmlTextWriter编剧)System.Web.UI.Page.ProcessRequestMain(Boolean includeStagesBeforeAsyncPoint,Boolean includeStagesAfterAsyncPoint)

如果我在错误的地方关闭datacontext,它会一直失败,不是吗?

编辑 - 数据上下文:

public class mvCmsContext : DataContext
{
    public mvCmsContext(): 
    base(ConfigurationManager.ConnectionStrings["ApplicationServices"].ConnectionString,XmlMappingSource.FromStream(Assembly.GetExecutingAssembly().GetManifestResourceStream("DomainModel.mvCmsMapping.map"))){
        Log = (StringWriter)HttpContext.Current.Items["linqToSqlLog"];
    }
public Table<DomainModel.Entities.Configuration> Configs { get { return this.GetTable<DomainModel.Entities.Configuration>(); } }
}    
Run Code Online (Sandbox Code Playgroud)

编辑以添加更新:这看起来更好吗?我会上传并试一试.

public class ConfigRepository : IConfigRepository
{
    private mvCmsContext context { get; set; }
    public ConfigRepository() { context = new mvCmsContext(); }

    private static Func<mvCmsContext, string, Configuration> _byName =
        CompiledQuery.Compile((mvCmsContext context, string configName) =>
            (from c in context.Configs
             where c.configName == configName
             select c).SingleOrDefault());
    static public Configuration ByName(string configName)
    {
        var result = (Configuration)HttpContext.Current.Cache.Get(configName);
        if (result == null)
        {
            using (var context = new mvCmsContext())
            {
                HttpContext.Current.Cache.Insert(configName, _byName(context, configName));
                result = (Configuration)HttpContext.Current.Cache.Get(configName);
            }
        }
        return result;
    }
Run Code Online (Sandbox Code Playgroud)

Jam*_*ris 6

您的问题是您将datacontext定义为静态.这意味着它由所有请求和线程共享.

如果有两个不同的请求命中静态datacontext,则会发生这种异常.ByName中的using部分将重新创建并处理datacontext,想象另一个请求正在使用datacontext,而这样做.......因此异常.

解决方案是使您的datacontext非静态.