像这样制作linq是否会导致连接池问题

时间:2012-05-14 03:30:39

标签: c# .net linq connection-pooling

如果我将dbContext作为全局变量打开,如下面的代码所示,与在每个函数中使用新的datacontext并将其包装在using块中相比,是否会导致连接池问题?

using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using LoopinDeals.Helper;

namespace LoopinDeals.Model
{
    public class DealUsersRepository
    {
        private DataClassesDataContext DbContext = new DataClassesDataContext();

        public void AddUser(string Email, string Password)
        {
            DealUser deal = new DealUser()
            {
                Email = Email,
                Password = Password,
                EmailVerified = true,
                LastLogin = DateTime.Now,
                AccountCreated = DateTime.Now,
                IsActive = true,
                RegistrationMethod = RegistrationType.Normal.ToString(),
                Subscribe = "true"
            };

            DbContext.DealUsers.InsertOnSubmit(deal);
            DbContext.SubmitChanges();
        }

        public void AddSignUpUser(string Email, string City)
        {
            try
            {
                DealUser UserData = new DealUser()
                    {
                        Email = Email,
                        City = City,
                        IsActive = false,
                        LastLogin = DateTime.Now
                    };
                DbContext.DealUsers.InsertOnSubmit(UserData);
            }
            catch (Exception ex)
            {               

            }
        }

        public void UpdateSignUpUser(string Email, string FirstName, string LastName, string Password, string Mobile, string City)
        {
            try
            {
                DealUser UserData = DbContext.DealUsers.Single(UD => UD.Email == Email);
                UserData.FirstName = FirstName;
                UserData.LastName = LastName;
                UserData.Password = Password;
                UserData.Mobile = Mobile;
                UserData.City = City;
                UserData.IsActive = true;
                UserData.LastLogin = DateTime.Now;
                DbContext.SubmitChanges();
            }
            catch (Exception ex)
            {

            }
        }


    }
}

描述

请注意,我没有写这个代码,它是外包的。它崩溃了以下错误消息,我试图找出如何解决它。

  '/'应用程序中的服务器错误。超时已过期。超时期限   在从池中获取连接之前已经过了。这可能有   之所以发生,是因为所有池化连接都在使用中,并且最大池大小   达成了。描述:期间发生了未处理的异常   执行当前的Web请求。请查看堆栈跟踪   有关错误及其来源的更多信息   代码。

     

异常详细信息:System.InvalidOperationException:超时已过期。   从中获取连接之前经过的超时时间   池。这可能是因为所有汇集的连接都在   已达到使用和最大池大小。

     

来源错误:

     

[没有相关的源代码行]

     

源文件:c:\ Windows \ Microsoft.NET \ Framework64 \ v2.0.50727 \ Temporary   ASP.NET Files \ root \ f44daa26 \ cce00cbd \ App_Web_b21g2v5x.5.cs行:0

     

堆栈追踪:

     

[InvalidOperationException:超时已过期。超时期限   在从池中获取连接之前已经过了。这可能有   之所以发生,是因为所有池化连接都在使用中,并且最大池大小   到了。]   System.Data.ProviderBase.DbConnectionFactory.GetConnection(的DbConnection   拥有连接)+6264689
  System.Data.ProviderBase.DbConnectionClosed.OpenConnection(的DbConnection   outerConnection,DbConnectionFactory connectionFactory)+6265031
  System.Data.SqlClient.SqlConnection.Open()+ 258 8   System.Data.Linq.SqlClient.SqlConnectionManager.UseConnection(IConnectionUser   user)+65 System.Data.Linq.SqlClient.SqlProvider.get_IsSqlCe()+33   System.Data.Linq.SqlClient.SqlProvider.InitializeProviderMode()+32
  System.Data.Linq.SqlClient.SqlProvider.System.Data.Linq.Provider.IProvider.Execute(表达式   查询)+63
  System.Data.Linq.DataQuery`1.System.Collections.Generic.IEnumerable.GetEnumerator()   +45 LoopinDeals.Model.SiteDetails..ctor()+253 LoopinDeals.Admin.Default..ctor()+76
  ASP.admin_default_aspx..ctor()in   c:\ Windows \ Microsoft.NET \ Framework64 \ v2.0.50727 \ Temporary ASP.NET   文件\ ROOT \ f44daa26 \ cce00cbd \ App_Web_b21g2v5x.5.cs:0
  __ASP.FastObjectFactory_app_web_b21g2v5x.Create_ASP_admin_default_aspx()   在c:\ Windows \ Microsoft.NET \ Framework64 \ v2.0.50727 \ Temporary ASP.NET中   文件\ ROOT \ f44daa26 \ cce00cbd \ App_Web_b21g2v5x.22.cs:0
  System.Web.Compilation.BuildManager.CreateInstanceFromVirtualPath(VirtualPath   virtualPath,Type requiredBaseType,HttpContext context,Boolean   allowCrossApp,Boolean noAssert)+138
  System.Web.UI.PageHandlerFactory.GetHandlerHelper(HttpContext context,   String requestType,VirtualPath virtualPath,String physicalPath)+50   System.Web.MaterializeHandlerExecutionStep.System.Web.HttpApplication.IExecutionStep.Execute()   +425 System.Web.HttpApplication.ExecuteStep(IExecutionStep step,Boolean& completedSynchronously)+263

我在这里添加了SiteDetailsConstructor,这是否可能导致连接池问题?

    public class SiteDetails
    {
        public DataClassesDataContext DbContext = new DataClassesDataContext();

        public SiteDetails()
        {
            var Details = from dtl in DbContext.SiteSettings
                          select dtl;

            foreach (var item in Details)
            {
                MetaIndexKeyword = item.MetaIndexKeyword;
                MetaIndexDesc = item.MetaIndexDesc;
                MetaIndexTitle = item.MetaIndexTitle;
                MetaGetPrefrenceKeyword = item.MetaGetPrefrenceKeyword;
                MetaGetPrefrenceDesc = item.MetaGetPrefrenceDesc;
                Logo = item.Logo;
                Favicon = item.Favicon;
                NoImage = item.NoImage;
                SiteName = item.SiteName;
                SiteTitle = item.SiteTitle;
                SiteUrl = item.SiteUrl;
                FbAndTwitterShareMessage = item.FbAndTwitterShareMessage;
                CharacterSet = item.CharacterSet;
                SiteMaintanance = item.SiteMaintanance;
                PasswordChar = item.PasswordChar;
                HtmlMetaKeyword = item.HtmlMetaKeyword;
                HtmlMetaDescription = item.HtmlMetaDescription;
                MetaDataGoogleSiteMap = item.MetaDataGoogleSiteMap;
                WebMasterEmail = item.WebMasterEmail;
                SupportEmail = item.SupportEmail;
                NoReplyName = item.NoReplyName;
                NoReplyEmail = item.NoReplyEmail;
                DeleteExpireDeals = item.DeleteExpireDeals;
                DealsPerPageBeforeLogin = item.DealsPerPageBeforeLogin;
                DealsPerPageAfterLogin = item.DealsPerPageAfterLogin;
                RecentViewDeals = item.RecentViewDeals;
                BoughtDeals = item.BoughtDeals;
                FbFanPage = item.FacebookFanPage;
                FbApplicationId = item.FbApplicationId;
                FbSecret = item.FbSecret;
                FbApiSharingDeals = item.FbApiSharingDeals;
                GoogleApiKey = item.GoogleApiKey;
                TwitterScreenName = item.TwitterScreenName;
                TwitterConsumerKey = item.TwitterConsumerKey;
                TwitterConsumerSecret = item.TwitterConsumerSecret;
                SharingAppId = item.SharingAppId;
                SharingAppSecret = item.SharingAppSecret;
                SharingCanvasURL = item.SharingCanvasURL;
                InviteMessage = item.InviteMessage;
                SharingMsgLink = item.SharingMsgLink;
                ShareMsgPicture = item.ShareMsgPicture;
                ShareMsgName = item.ShareMsgName;
                ShareMsgCaption = item.ShareMsgCaption;
                ShareMsgDesc = item.ShareMsgDesc;
            }

        }

        public static string MetaIndexKeyword { get; set; }
        public static string MetaIndexDesc { get; set; }
        public static string MetaIndexTitle { get; set; }
        public static string MetaGetPrefrenceKeyword { get; set; }
        public static string MetaGetPrefrenceDesc { get; set; }
        public static string Logo { get; set; }
        public static string Favicon { get; set; }
        public static string NoImage { get; set; }
        public static string SiteName { get; set; }
        public static string SiteTitle { get; set; }
        public static string SiteUrl { get; set; }
        public static string FbAndTwitterShareMessage { get; set; }
        public static string CharacterSet { get; set; }
        public static string SiteMaintanance { get; set; }
        public static string PasswordChar { get; set; }
        public static string HtmlMetaKeyword { get; set; }
        public static string HtmlMetaDescription { get; set; }
        public static string MetaDataGoogleSiteMap { get; set; }
        public static string WebMasterEmail { get; set; }
        public static string SupportEmail { get; set; }
        public static string NoReplyName { get; set; }
        public static string NoReplyEmail { get; set; }
        public static bool? DeleteExpireDeals { get; set; }
        public static int? DealsPerPageBeforeLogin { get; set; }
        public static int? DealsPerPageAfterLogin { get; set; }
        public static int? RecentViewDeals { get; set; }
        public static int? BoughtDeals { get; set; }
        public static string FbFanPage { get; set; }
        public static string FbApplicationId { get; set; }
        public static string FbSecret { get; set; }
        public static string FbApiSharingDeals { get; set; }
        public static string GoogleApiKey { get; set; }
        public static string TwitterScreenName { get; set; }
        public static string TwitterConsumerKey { get; set; }
        public static string TwitterConsumerSecret { get; set; }

        public static string SharingAppId { get; set; }
        public static string SharingAppSecret { get; set; }
        public static string SharingCanvasURL { get; set; }
        public static string InviteMessage { get; set; }
        public static string SharingMsgLink { get; set; }
        public static string ShareMsgPicture { get; set; }
        public static string ShareMsgName { get; set; }
        public static string ShareMsgCaption { get; set; }
        public static string ShareMsgDesc { get; set; }

    }
}

2 个答案:

答案 0 :(得分:6)

它不应导致连接池问题,因为只有在调用SubmitChanges时才打开,使用和关闭数据库连接。

由于DBContext不是线程安全的,因此如果您的存储库实例被多个线程使用,则会导致问题。

另一个问题是在DBContext实例中缓存EF所做的数据 - 如果你不处理DBContext实例,这个缓存的数据会累积,并且会在一段时间后变得非常大,直至导致内存压力。

由于这两个原因(并且重新创建上下文没有太多开销),将DBContext用法保留在使用块中总体上更好。

答案 1 :(得分:5)

全局管理上下文不会导致连接池问题。但是,上下文包含DBSets,其中包含所有访问的数据,因此上下文将会增长,直到内存不足(假设您的DB大于可用内存)。

但是上下文创建起来很便宜,你为什么要全局管理?

- 对新信息的回应

我认为您所展示的代码片段根本不在问题背后。相反,从查看代码跟踪,问题似乎发生在SiteDetails的构造函数中。这个构造函数是否加载了大量数据?如果是os,你可能只是压倒数据库,因为有太多的线程试图加载太多的数据。