[ResourceExposure(ResourceScope.Machine)] //Exposes the file names which are a Machine resource as part of the connection string
        private void ChangeConnectionString(string newConnectionString)
        {
            DbConnectionOptions userConnectionOptions = s_emptyConnectionOptions;
            if (!String.IsNullOrEmpty(newConnectionString))
            {
                userConnectionOptions = new DbConnectionOptions(newConnectionString, EntityConnectionStringBuilder.Synonyms);
            }

            DbProviderFactory factory = null;
            DbConnection storeConnection = null;
            DbConnectionOptions effectiveConnectionOptions = userConnectionOptions;

            if (!userConnectionOptions.IsEmpty)
            {
                // Check if we have the named connection, if yes, then use the connection string from the configuration manager settings
                string namedConnection = userConnectionOptions[EntityConnectionStringBuilder.NameParameterName];
                if (!string.IsNullOrEmpty(namedConnection))
                {
                    // There cannot be other parameters when the named connection is specified
                    if (1 < userConnectionOptions.Parsetable.Count)
                    {
                        throw EntityUtil.Argument(System.Data.Entity.Strings.EntityClient_ExtraParametersWithNamedConnection);
                    }

                    // Find the named connection from the configuration, then extract the settings
                    ConnectionStringSettings setting = ConfigurationManager.ConnectionStrings[namedConnection];
                    if (setting == null || setting.ProviderName != EntityConnection.s_entityClientProviderName)
                    {
                        throw EntityUtil.Argument(System.Data.Entity.Strings.EntityClient_InvalidNamedConnection);
                    }

                    effectiveConnectionOptions = new DbConnectionOptions(setting.ConnectionString, EntityConnectionStringBuilder.Synonyms);

                    // Check for a nested Name keyword
                    string nestedNamedConnection = effectiveConnectionOptions[EntityConnectionStringBuilder.NameParameterName];
                    if (!string.IsNullOrEmpty(nestedNamedConnection))
                    {
                        throw EntityUtil.Argument(System.Data.Entity.Strings.EntityClient_NestedNamedConnection(namedConnection));
                    }
                }

                //Validate the connection string has the required Keywords( Provider and Metadata)
                //We trim the values for both the Keywords, so a string value with only spaces will throw an exception
                //reporting back to the user that the Keyword was missing.
                ValidateValueForTheKeyword(effectiveConnectionOptions, EntityConnectionStringBuilder.MetadataParameterName);

                string providerName = ValidateValueForTheKeyword(effectiveConnectionOptions, EntityConnectionStringBuilder.ProviderParameterName);
                // Get the correct provider factory
                factory = GetFactory(providerName);

                // Create the underlying provider specific connection and give it the connection string from the DbConnectionOptions object
                storeConnection = GetStoreConnection(factory);

                try
                {
                    // When the value of 'Provider Connection String' is null, it means it has not been present in the entity connection string at all.
                    // Providers should still be able handle empty connection strings since those may be explicitly passed by clients.
                    string providerConnectionString = effectiveConnectionOptions[EntityConnectionStringBuilder.ProviderConnectionStringParameterName];
                    if (providerConnectionString != null)
                    {
                        storeConnection.ConnectionString = providerConnectionString;
                    }
                }
                catch (Exception e)
                {
                    if (EntityUtil.IsCatchableExceptionType(e))
                    {
                        throw EntityUtil.Provider(@"ConnectionString", e);
                    }
                    throw;
                }
            }
            
            // This lock is to ensure that the connection string matches with the provider connection and metadata workspace that's being
            // managed by this EntityConnection, so states in this connection object are not messed up.
            // It's not for security, but just to help reduce user error.
            lock (_connectionStringLock)
            {
                // Now we have sufficient information and verified the configuration string is good, use them for this connection object
                // Failure should not occur from this point to the end of this method
                this._providerFactory = factory;
                this._metadataWorkspace = null;

                ClearTransactions();
                ResetStoreConnection(storeConnection, null, false);

                // Remembers the connection options objects with the connection string set by the user
                this._userConnectionOptions = userConnectionOptions;
                this._effectiveConnectionOptions = effectiveConnectionOptions;
            }
        }
Exemple #2
0
        internal DbConnectionInternal CreatePooledConnection(DbConnectionPool pool, DbConnection owningObject, DbConnectionOptions options, DbConnectionPoolKey poolKey, DbConnectionOptions userOptions)
        {
            Debug.Assert(null != pool, "null pool?");
            DbConnectionPoolGroupProviderInfo poolGroupProviderInfo = pool.PoolGroup.ProviderInfo;

            DbConnectionInternal newConnection = CreateConnection(options, poolKey, poolGroupProviderInfo, pool, owningObject, userOptions);

            if (null != newConnection)
            {
                PerformanceCounters.HardConnectsPerSecond.Increment();
                newConnection.MakePooledConnection(pool);
            }
            return(newConnection);
        }
 internal virtual bool TryReplaceConnection(DbConnection outerConnection, DbConnectionFactory connectionFactory, TaskCompletionSource <DbConnectionInternal> retry, DbConnectionOptions userOptions)
 {
     throw ADP.MethodNotImplemented("TryReplaceConnection");
 }
Exemple #4
0
 protected abstract DbConnectionInternal CreateConnection(DbConnectionOptions options, DbConnectionPoolKey poolKey, object poolGroupProviderInfo, DbConnectionPool pool, DbConnection owningConnection);
Exemple #5
0
 protected abstract DbConnectionPoolGroupOptions CreateConnectionPoolGroupOptions(DbConnectionOptions options);
Exemple #6
0
 internal virtual DbConnectionPoolGroupProviderInfo CreateConnectionPoolGroupProviderInfo(DbConnectionOptions connectionOptions)
 {
     return(null);
 }
Exemple #7
0
        internal DbConnectionPoolGroup GetConnectionPoolGroup(DbConnectionPoolKey key, DbConnectionPoolGroupOptions poolOptions, ref DbConnectionOptions userConnectionOptions)
        {
            if (ADP.IsEmpty(key.ConnectionString))
            {
                return((DbConnectionPoolGroup)null);
            }

            DbConnectionPoolGroup connectionPoolGroup;
            Dictionary <DbConnectionPoolKey, DbConnectionPoolGroup> connectionPoolGroups = _connectionPoolGroups;

            if (!connectionPoolGroups.TryGetValue(key, out connectionPoolGroup) || (connectionPoolGroup.IsDisabled && (null != connectionPoolGroup.PoolGroupOptions)))
            {
                // If we can't find an entry for the connection string in
                // our collection of pool entries, then we need to create a
                // new pool entry and add it to our collection.

                DbConnectionOptions connectionOptions = CreateConnectionOptions(key.ConnectionString, userConnectionOptions);
                if (null == connectionOptions)
                {
                    throw ADP.InternalConnectionError(ADP.ConnectionError.ConnectionOptionsMissing);
                }

                string expandedConnectionString = key.ConnectionString;
                if (null == userConnectionOptions)
                { // we only allow one expansion on the connection string
                    userConnectionOptions    = connectionOptions;
                    expandedConnectionString = connectionOptions.Expand();

                    // if the expanded string is same instance (default implementation), the use the already created options
                    if ((object)expandedConnectionString != (object)key.ConnectionString)
                    {
                        // CONSIDER: caching the original string to reduce future parsing
                        DbConnectionPoolKey newKey = (DbConnectionPoolKey)((ICloneable)key).Clone();
                        newKey.ConnectionString = expandedConnectionString;
                        return(GetConnectionPoolGroup(newKey, null, ref userConnectionOptions));
                    }
                }

                // We don't support connection pooling on Win9x; it lacks too many of the APIs we require.
                if ((null == poolOptions) && ADP.IsWindowsNT)
                {
                    if (null != connectionPoolGroup)
                    {
                        // reusing existing pool option in case user originally used SetConnectionPoolOptions
                        poolOptions = connectionPoolGroup.PoolGroupOptions;
                    }
                    else
                    {
                        // Note: may return null for non-pooled connections
                        poolOptions = CreateConnectionPoolGroupOptions(connectionOptions);
                    }
                }

                lock (this)
                {
                    connectionPoolGroups = _connectionPoolGroups;
                    if (!connectionPoolGroups.TryGetValue(key, out connectionPoolGroup))
                    {
                        DbConnectionPoolGroup newConnectionPoolGroup = new DbConnectionPoolGroup(connectionOptions, key, poolOptions);
                        newConnectionPoolGroup.ProviderInfo = CreateConnectionPoolGroupProviderInfo(connectionOptions);

                        // build new dictionary with space for new connection string
                        Dictionary <DbConnectionPoolKey, DbConnectionPoolGroup> newConnectionPoolGroups = new Dictionary <DbConnectionPoolKey, DbConnectionPoolGroup>(1 + connectionPoolGroups.Count);
                        foreach (KeyValuePair <DbConnectionPoolKey, DbConnectionPoolGroup> entry in connectionPoolGroups)
                        {
                            newConnectionPoolGroups.Add(entry.Key, entry.Value);
                        }

                        // lock prevents race condition with PruneConnectionPoolGroups
                        newConnectionPoolGroups.Add(key, newConnectionPoolGroup);
                        PerformanceCounters.NumberOfActiveConnectionPoolGroups.Increment();
                        connectionPoolGroup   = newConnectionPoolGroup;
                        _connectionPoolGroups = newConnectionPoolGroups;
                    }
                    else
                    {
                        Debug.Assert(!connectionPoolGroup.IsDisabled, "Disabled pool entry discovered");
                    }
                }
                Debug.Assert(null != connectionPoolGroup, "how did we not create a pool entry?");
                Debug.Assert(null != userConnectionOptions, "how did we not have user connection options?");
            }
            else if (null == userConnectionOptions)
            {
                userConnectionOptions = connectionPoolGroup.ConnectionOptions;
            }
            return(connectionPoolGroup);
        }
        public IUnitOfWork GetUnitOfWork(Type dbContextType, string dbName = null)
        {
            Check.NotNull(dbContextType, nameof(dbContextType));
            // 若替换之前的UnitOfWork则有可能造成数据库连接释放不及时
            // 若使用锁,可以确保UnitOrWork在当前Scope生命周期的唯一性,但会影响性能
            var key = string.Format("{0}${1}$", dbName, dbContextType.FullName);

            if (_works.ContainsKey(key))
            {
                return(_works[key]);
            }
            else
            {
                foreach (var k in _works.Keys)
                {
                    if (k.StartsWith(key))
                    {
                        return(_works[k]);
                    }
                }

                IDbContext dbContext;
                key += DateTime.Now.Ticks.ToString();
                var dbConnectionOptionsMap = _serviceProvider.GetRequiredService <IOptions <AlasFx.Options.AlasFxOptions> >().Value.DbConnections;
                if (dbConnectionOptionsMap == null || dbConnectionOptionsMap.Count <= 0)
                {
                    throw new AlasFxException("无法获取数据库配置");
                }

                DbConnectionOptions dbConnectionOptions = dbName == null?dbConnectionOptionsMap.First().Value : dbConnectionOptionsMap[dbName];

                var builderOptions = _serviceProvider.GetServices <DbContextOptionsBuilderOptions>()
                                     ?.Where(d => (d.DbName == null || d.DbName == dbName) && (d.DbContextType == null || d.DbContextType == dbContextType))
                                     ?.OrderByDescending(d => d.DbName)
                                     ?.OrderByDescending(d => d.DbContextType);
                if (builderOptions == null || !builderOptions.Any())
                {
                    throw new AlasFxException("无法获取匹配的DbContextOptionsBuilder");
                }

                var dbUser = _serviceProvider.GetServices <IDbContextOptionsBuilderUser>()?.FirstOrDefault(u => u.Type == dbConnectionOptions.DatabaseType);
                if (dbUser == null)
                {
                    throw new AlasFxException($"无法解析类型为“{dbConnectionOptions.DatabaseType}”的 {typeof(IDbContextOptionsBuilderUser).FullName} 实例");
                }


                var dbContextOptions = dbUser.Use(builderOptions.First().Builder, dbConnectionOptions.ConnectionString).Options;
                if (_expressionFactoryDict.TryGetValue(dbContextType, out Func <IServiceProvider, DbContextOptions, IDbContext> factory))
                {
                    dbContext = factory(_serviceProvider, dbContextOptions);
                }
                else
                {
                    // 使用Expression创建DbContext
                    var constructorMethod = dbContextType.GetConstructors()
                                            .Where(c => c.IsPublic && !c.IsAbstract && !c.IsStatic)
                                            .OrderByDescending(c => c.GetParameters().Length)
                                            .FirstOrDefault();
                    if (constructorMethod == null)
                    {
                        throw new AlasFxException("无法获取有效的上下文构造器");
                    }

                    var dbContextOptionsBuilderType = typeof(DbContextOptionsBuilder <>);
                    var dbContextOptionsType        = typeof(DbContextOptions);
                    var dbContextOptionsGenericType = typeof(DbContextOptions <>);
                    var serviceProviderType         = typeof(IServiceProvider);
                    var getServiceMethod            = serviceProviderType.GetMethod("GetService");
                    var lambdaParameterExpressions  = new ParameterExpression[2];
                    lambdaParameterExpressions[0] = (Expression.Parameter(serviceProviderType, "serviceProvider"));
                    lambdaParameterExpressions[1] = (Expression.Parameter(dbContextOptionsType, "dbContextOptions"));
                    var paramTypes          = constructorMethod.GetParameters();
                    var argumentExpressions = new Expression[paramTypes.Length];
                    for (int i = 0; i < paramTypes.Length; i++)
                    {
                        var pType = paramTypes[i];
                        if (pType.ParameterType == dbContextOptionsType ||
                            (pType.ParameterType.IsGenericType && pType.ParameterType.GetGenericTypeDefinition() == dbContextOptionsGenericType))
                        {
                            argumentExpressions[i] = Expression.Convert(lambdaParameterExpressions[1], pType.ParameterType);
                        }
                        else if (pType.ParameterType == serviceProviderType)
                        {
                            argumentExpressions[i] = lambdaParameterExpressions[0];
                        }
                        else
                        {
                            argumentExpressions[i] = Expression.Call(lambdaParameterExpressions[0], getServiceMethod);
                        }
                    }

                    factory = Expression
                              .Lambda <Func <IServiceProvider, DbContextOptions, IDbContext> >(
                        Expression.Convert(Expression.New(constructorMethod, argumentExpressions), typeof(IDbContext)), lambdaParameterExpressions.AsEnumerable())
                              .Compile();
                    _expressionFactoryDict.TryAdd(dbContextType, factory);

                    dbContext = factory(_serviceProvider, dbContextOptions);
                }

                var unitOfWorkFactory = _serviceProvider.GetRequiredService <IUnitOfWorkFactory>();
                var unitOfWork        = unitOfWorkFactory.GetUnitOfWork(_serviceProvider, dbContext);
                _works.Add(key, unitOfWork);
                return(unitOfWork);
            }
        }
Exemple #9
0
        protected override DbConnectionOptions CreateConnectionOptions(string connectionString, DbConnectionOptions previous)
        {
            Debug.Assert(!string.IsNullOrEmpty(connectionString), "empty connectionString");
            SqlConnectionString result = new SqlConnectionString(connectionString);

            return(result);
        }
Exemple #10
0
 /// <summary>
 /// Initializes a new instance of the class.
 /// </summary>
 public OleDbDataSource(DbConnectionOptions connectionOptions)
     : base(connectionOptions)
 {
 }
Exemple #11
0
 /// <summary>
 /// Builds a connection string based on the specified connection settings.
 /// </summary>
 public override string BuildConnectionString(DbConnectionOptions connectionOptions)
 {
     return("");
 }
Exemple #12
0
        internal override bool TryOpenConnection(DbConnection outerConnection, DbConnectionFactory connectionFactory, TaskCompletionSource <DbConnectionInternal> retry, DbConnectionOptions userOptions)
        {
            if (retry == null || !retry.Task.IsCompleted)
            {
                // retry is null if this is a synchronous call

                // if someone calls Open or OpenAsync while in this state,
                // then the retry task will not be completed

                throw ADP.ConnectionAlreadyOpen(State);
            }

            // we are completing an asynchronous open
            Debug.Assert(retry.Task.Status == TaskStatus.RanToCompletion, "retry task must be completed successfully");
            DbConnectionInternal openConnection = retry.Task.Result;

            if (null == openConnection)
            {
                connectionFactory.SetInnerConnectionTo(outerConnection, this);
                throw ADP.InternalConnectionError(ADP.ConnectionError.GetConnectionReturnsNull);
            }
            connectionFactory.SetInnerConnectionEvent(outerConnection, openConnection);

            return(true);
        }
Exemple #13
0
 internal override bool TryReplaceConnection(DbConnection outerConnection, DbConnectionFactory connectionFactory, TaskCompletionSource <DbConnectionInternal> retry, DbConnectionOptions userOptions)
 => TryOpenConnection(outerConnection, connectionFactory, retry, userOptions);
Exemple #14
0
 /// <summary>
 /// Builds a connection string based on the specified connection settings.
 /// </summary>
 public override string BuildConnectionString(DbConnectionOptions connectionOptions)
 {
     return(BuildSqlConnectionString(connectionOptions));
 }
        [ResourceExposure(ResourceScope.Machine)] //Exposes the file names which are a Machine resource as part of the connection string
        private void ChangeConnectionString(string newConnectionString)
        {
            var userConnectionOptions = _emptyConnectionOptions;
            if (!String.IsNullOrEmpty(newConnectionString))
            {
                userConnectionOptions = new DbConnectionOptions(newConnectionString, EntityConnectionStringBuilder.ValidKeywords);
            }

            DbProviderFactory factory = null;
            DbConnection storeConnection = null;
            var effectiveConnectionOptions = userConnectionOptions;

            if (!userConnectionOptions.IsEmpty)
            {
                // Check if we have the named connection, if yes, then use the connection string from the configuration manager settings
                var namedConnection = userConnectionOptions[EntityConnectionStringBuilder.NameParameterName];
                if (!string.IsNullOrEmpty(namedConnection))
                {
                    // There cannot be other parameters when the named connection is specified
                    if (1 < userConnectionOptions.Parsetable.Count)
                    {
                        throw new ArgumentException(Strings.EntityClient_ExtraParametersWithNamedConnection);
                    }

                    // Find the named connection from the configuration, then extract the settings
                    var setting = ConfigurationManager.ConnectionStrings[namedConnection];
                    if (setting == null
                        || setting.ProviderName != EntityClientProviderName)
                    {
                        throw new ArgumentException(Strings.EntityClient_InvalidNamedConnection);
                    }

                    effectiveConnectionOptions = new DbConnectionOptions(
                        setting.ConnectionString, EntityConnectionStringBuilder.ValidKeywords);

                    // Check for a nested Name keyword
                    var nestedNamedConnection = effectiveConnectionOptions[EntityConnectionStringBuilder.NameParameterName];
                    if (!string.IsNullOrEmpty(nestedNamedConnection))
                    {
                        throw new ArgumentException(Strings.EntityClient_NestedNamedConnection(namedConnection));
                    }
                }

                //Validate the connection string has the required Keywords( Provider and Metadata)
                //We trim the values for both the Keywords, so a string value with only spaces will throw an exception
                //reporting back to the user that the Keyword was missing.
                ValidateValueForTheKeyword(effectiveConnectionOptions, EntityConnectionStringBuilder.MetadataParameterName);

                var providerName = ValidateValueForTheKeyword(
                    effectiveConnectionOptions, EntityConnectionStringBuilder.ProviderParameterName);
                // Get the correct provider factory
                factory = DbConfiguration.DependencyResolver.GetService<DbProviderFactory>(providerName);

                // Create the underlying provider specific connection and give it the connection string from the DbConnectionOptions object
                storeConnection = GetStoreConnection(factory);

                try
                {
                    // When the value of 'Provider Connection String' is null, it means it has not been present in the entity connection string at all.
                    // Providers should still be able handle empty connection strings since those may be explicitly passed by clients.
                    var providerConnectionString =
                        effectiveConnectionOptions[EntityConnectionStringBuilder.ProviderConnectionStringParameterName];
                    if (providerConnectionString != null)
                    {
                        DbInterception.Dispatch.Connection.SetConnectionString(
                            storeConnection,
                            new DbConnectionPropertyInterceptionContext<string>(InterceptionContext).WithValue(providerConnectionString));
                    }
                }
                catch (Exception e)
                {
                    if (e.IsCatchableExceptionType())
                    {
                        throw new EntityException(Strings.EntityClient_ProviderSpecificError(@"ConnectionString"), e);
                    }

                    throw;
                }
            }

            // This lock is to ensure that the connection string matches with the provider connection and metadata workspace that's being
            // managed by this EntityConnection, so states in this connection object are not messed up.
            // It's not for security, but just to help reduce user error.
            lock (_connectionStringLock)
            {
                // Now we have sufficient information and verified the configuration string is good, use them for this connection object
                // Failure should not occur from this point to the end of this method
                _providerFactory = factory;

                _metadataWorkspace = null;

                ClearTransactions();
                UnsubscribeFromStoreConnectionStateChangeEvents();
                _storeConnection = storeConnection;
                SubscribeToStoreConnectionStateChangeEvents();

                // Remembers the connection options objects with the connection string set by the user
                _userConnectionOptions = userConnectionOptions;
                _effectiveConnectionOptions = effectiveConnectionOptions;
            }
        }
Exemple #16
0
        override internal DbConnectionPoolProviderInfo CreateConnectionPoolProviderInfo(DbConnectionOptions connectionOptions)
        {
            DbConnectionPoolProviderInfo providerInfo = null;

            if (((SqlConnectionString)connectionOptions).UserInstance)
            {
                providerInfo = new SqlConnectionPoolProviderInfo();
            }

            return(providerInfo);
        }
Exemple #17
0
 /// <summary>
 /// Initializes a new instance of the class.
 /// </summary>
 public SqlDataSource(DbConnectionOptions connectionOptions)
     : base(connectionOptions)
 {
 }
Exemple #18
0
        override protected DbConnectionPoolGroupOptions CreateConnectionPoolGroupOptions(DbConnectionOptions connectionOptions)
        {
            SqlConnectionString opt = (SqlConnectionString)connectionOptions;

            DbConnectionPoolGroupOptions poolingOptions = null;

            if (opt.Pooling)
            {    // never pool context connections.
                int connectionTimeout = opt.ConnectTimeout;

                if ((0 < connectionTimeout) && (connectionTimeout < int.MaxValue / 1000))
                {
                    connectionTimeout *= 1000;
                }
                else if (connectionTimeout >= int.MaxValue / 1000)
                {
                    connectionTimeout = int.MaxValue;
                }

                if (opt.Authentication == SqlAuthenticationMethod.ActiveDirectoryInteractive || opt.Authentication == SqlAuthenticationMethod.ActiveDirectoryDeviceCodeFlow)
                {
                    // interactive/device code flow mode will always have pool's CreateTimeout = 10 x ConnectTimeout.
                    if (connectionTimeout >= Int32.MaxValue / 10)
                    {
                        connectionTimeout = Int32.MaxValue;
                    }
                    else
                    {
                        connectionTimeout *= 10;
                    }
                    SqlClientEventSource.Log.TraceEvent("<sc.SqlConnectionFactory.CreateConnectionPoolGroupOptions>Set connection pool CreateTimeout={0} when {1} is in use.", connectionTimeout, opt.Authentication);
                }
                poolingOptions = new DbConnectionPoolGroupOptions(
                    opt.IntegratedSecurity,
                    opt.MinPoolSize,
                    opt.MaxPoolSize,
                    connectionTimeout,
                    opt.LoadBalanceTimeout,
                    opt.Enlist);
            }
            return(poolingOptions);
        }
Exemple #19
0
        internal bool TryGetConnection(DbConnection owningConnection, TaskCompletionSource <DbConnectionInternal> retry, DbConnectionOptions userOptions, DbConnectionInternal oldConnection, out DbConnectionInternal connection)
        {
            Debug.Assert(null != owningConnection, "null owningConnection?");

            DbConnectionPoolGroup poolGroup;
            DbConnectionPool      connectionPool;

            connection = null;

            //  Work around race condition with clearing the pool between GetConnectionPool obtaining pool
            //  and GetConnection on the pool checking the pool state.  Clearing the pool in this window
            //  will switch the pool into the ShuttingDown state, and GetConnection will return null.
            //  There is probably a better solution involving locking the pool/group, but that entails a major
            //  re-design of the connection pooling synchronization, so is post-poned for now.

            // use retriesLeft to prevent CPU spikes with incremental sleep
            // start with one msec, double the time every retry
            // max time is: 1 + 2 + 4 + ... + 2^(retries-1) == 2^retries -1 == 1023ms (for 10 retries)
            int retriesLeft = 10;
            int timeBetweenRetriesMilliseconds = 1;

            do
            {
                poolGroup = GetConnectionPoolGroup(owningConnection);
                // Doing this on the callers thread is important because it looks up the WindowsIdentity from the thread.
                connectionPool = GetConnectionPool(owningConnection, poolGroup);
                if (null == connectionPool)
                {
                    // If GetConnectionPool returns null, we can be certain that
                    // this connection should not be pooled via DbConnectionPool
                    // or have a disabled pool entry.
                    poolGroup = GetConnectionPoolGroup(owningConnection); // previous entry have been disabled

                    if (retry != null)
                    {
                        Task <DbConnectionInternal> newTask;
                        CancellationTokenSource     cancellationTokenSource = new CancellationTokenSource();
                        lock (s_pendingOpenNonPooled)
                        {
                            // look for an available task slot (completed or empty)
                            int idx;
                            for (idx = 0; idx < s_pendingOpenNonPooled.Length; idx++)
                            {
                                Task task = s_pendingOpenNonPooled[idx];
                                if (task == null)
                                {
                                    s_pendingOpenNonPooled[idx] = GetCompletedTask();
                                    break;
                                }
                                else if (task.IsCompleted)
                                {
                                    break;
                                }
                            }

                            // if didn't find one, pick the next one in round-robbin fashion
                            if (idx == s_pendingOpenNonPooled.Length)
                            {
                                idx = s_pendingOpenNonPooledNext++ % s_pendingOpenNonPooled.Length;
                            }

                            // now that we have an antecedent task, schedule our work when it is completed.
                            // If it is a new slot or a compelted task, this continuation will start right away.
                            // BUG? : If we have timed out task on top of running task, then new task could be started
                            // on top of that, since we are only checking the top task. This will lead to starting more threads
                            // than intended.
                            newTask = s_pendingOpenNonPooled[idx].ContinueWith((_) =>
                            {
                                Transactions.Transaction originalTransaction = ADP.GetCurrentTransaction();
                                try
                                {
                                    ADP.SetCurrentTransaction(retry.Task.AsyncState as Transactions.Transaction);
                                    var newConnection = CreateNonPooledConnection(owningConnection, poolGroup, userOptions);
                                    if ((oldConnection != null) && (oldConnection.State == ConnectionState.Open))
                                    {
                                        oldConnection.PrepareForReplaceConnection();
                                        oldConnection.Dispose();
                                    }
                                    return(newConnection);
                                }
                                finally
                                {
                                    ADP.SetCurrentTransaction(originalTransaction);
                                }
                            }, cancellationTokenSource.Token, TaskContinuationOptions.LongRunning, TaskScheduler.Default);

                            // Place this new task in the slot so any future work will be queued behind it
                            s_pendingOpenNonPooled[idx] = newTask;
                        }

                        // Set up the timeout (if needed)
                        if (owningConnection.ConnectionTimeout > 0)
                        {
                            int connectionTimeoutMilliseconds = owningConnection.ConnectionTimeout * 1000;
                            cancellationTokenSource.CancelAfter(connectionTimeoutMilliseconds);
                        }

                        // once the task is done, propagate the final results to the original caller
                        newTask.ContinueWith((task) =>
                        {
                            cancellationTokenSource.Dispose();
                            if (task.IsCanceled)
                            {
                                retry.TrySetException(ADP.ExceptionWithStackTrace(ADP.NonPooledOpenTimeout()));
                            }
                            else if (task.IsFaulted)
                            {
                                retry.TrySetException(task.Exception.InnerException);
                            }
                            else
                            {
                                if (retry.TrySetResult(task.Result))
                                {
                                    PerformanceCounters.NumberOfNonPooledConnections.Increment();
                                }
                                else
                                {
                                    // The outer TaskCompletionSource was already completed
                                    // Which means that we don't know if someone has messed with the outer connection in the middle of creation
                                    // So the best thing to do now is to destroy the newly created connection
                                    task.Result.DoomThisConnection();
                                    task.Result.Dispose();
                                }
                            }
                        }, TaskScheduler.Default);

                        return(false);
                    }

                    connection = CreateNonPooledConnection(owningConnection, poolGroup, userOptions);
                    PerformanceCounters.NumberOfNonPooledConnections.Increment();
                }
                else
                {
                    if (((System.Data.OleDb.OleDbConnection)owningConnection).ForceNewConnection)
                    {
                        Debug.Assert(!(oldConnection is DbConnectionClosed), "Force new connection, but there is no old connection");
                        connection = connectionPool.ReplaceConnection(owningConnection, userOptions, oldConnection);
                    }
                    else
                    {
                        if (!connectionPool.TryGetConnection(owningConnection, retry, userOptions, out connection))
                        {
                            return(false);
                        }
                    }

                    if (connection == null)
                    {
                        // connection creation failed on semaphore waiting or if max pool reached
                        if (connectionPool.IsRunning)
                        {
                            // If GetConnection failed while the pool is running, the pool timeout occurred.
                            throw ADP.PooledOpenTimeout();
                        }
                        else
                        {
                            // We've hit the race condition, where the pool was shut down after we got it from the group.
                            // Yield time slice to allow shut down activities to complete and a new, running pool to be instantiated
                            //  before retrying.
                            Threading.Thread.Sleep(timeBetweenRetriesMilliseconds);
                            timeBetweenRetriesMilliseconds *= 2; // double the wait time for next iteration
                        }
                    }
                }
            } while (connection == null && retriesLeft-- > 0);

            if (connection == null)
            {
                // exhausted all retries or timed out - give up
                throw ADP.PooledOpenTimeout();
            }

            return(true);
        }
Exemple #20
0
 override internal DbConnectionPoolGroupProviderInfo CreateConnectionPoolGroupProviderInfo(DbConnectionOptions connectionOptions)
 {
     return(new SqlConnectionPoolGroupProviderInfo((SqlConnectionString)connectionOptions));
 }
Exemple #21
0
 protected virtual DbConnectionInternal CreateConnection(DbConnectionOptions options, DbConnectionPoolKey poolKey, object poolGroupProviderInfo, DbConnectionPool pool, DbConnection owningConnection, DbConnectionOptions userOptions)
 {
     return(CreateConnection(options, poolKey, poolGroupProviderInfo, pool, owningConnection));
 }
Exemple #22
0
 override protected DbConnectionInternal CreateConnection(DbConnectionOptions options, DbConnectionPoolKey poolKey, object poolGroupProviderInfo, DbConnectionPool pool, DbConnection owningConnection)
 {
     return(CreateConnection(options, poolKey, poolGroupProviderInfo, pool, owningConnection, userOptions: null));
 }
Exemple #23
0
 protected abstract DbConnectionOptions CreateConnectionOptions(string connectionString, DbConnectionOptions previous);
Exemple #24
0
        override protected DbConnectionInternal CreateConnection(DbConnectionOptions options, DbConnectionPoolKey poolKey, object poolGroupProviderInfo, DbConnectionPool pool, DbConnection owningConnection, DbConnectionOptions userOptions)
        {
            SqlConnectionString  opt = (SqlConnectionString)options;
            SqlConnectionPoolKey key = (SqlConnectionPoolKey)poolKey;
            SessionData          recoverySessionData = null;

            SqlConnection sqlOwningConnection         = (SqlConnection)owningConnection;
            bool          applyTransientFaultHandling = sqlOwningConnection != null ? sqlOwningConnection._applyTransientFaultHandling : false;

            SqlConnectionString userOpt = null;

            if (userOptions != null)
            {
                userOpt = (SqlConnectionString)userOptions;
            }
            else if (sqlOwningConnection != null)
            {
                userOpt = (SqlConnectionString)(sqlOwningConnection.UserConnectionOptions);
            }

            if (sqlOwningConnection != null)
            {
                recoverySessionData = sqlOwningConnection._recoverySessionData;
            }

            bool redirectedUserInstance       = false;
            DbConnectionPoolIdentity identity = null;

            // Pass DbConnectionPoolIdentity to SqlInternalConnectionTds if using integrated security.
            // Used by notifications.
            if (opt.IntegratedSecurity)
            {
                if (pool != null)
                {
                    identity = pool.Identity;
                }
                else
                {
                    identity = DbConnectionPoolIdentity.GetCurrent();
                }
            }

            // FOLLOWING IF BLOCK IS ENTIRELY FOR SSE USER INSTANCES
            // If "user instance=true" is in the connection string, we're using SSE user instances
            if (opt.UserInstance)
            {
                // opt.DataSource is used to create the SSE connection
                redirectedUserInstance = true;
                string instanceName;

                if ((null == pool) ||
                    (null != pool && pool.Count <= 0))
                { // Non-pooled or pooled and no connections in the pool.
                    SqlInternalConnectionTds sseConnection = null;
                    try
                    {
                        // We throw an exception in case of a failure
                        // NOTE: Cloning connection option opt to set 'UserInstance=True' and 'Enlist=False'
                        //       This first connection is established to SqlExpress to get the instance name
                        //       of the UserInstance.
                        SqlConnectionString sseopt = new SqlConnectionString(opt, opt.DataSource, userInstance: true, setEnlistValue: false);
                        sseConnection = new SqlInternalConnectionTds(identity, sseopt, key.Credential, null, "", null, false, applyTransientFaultHandling: applyTransientFaultHandling);
                        // NOTE: Retrieve <UserInstanceName> here. This user instance name will be used below to connect to the Sql Express User Instance.
                        instanceName = sseConnection.InstanceName;

                        if (!instanceName.StartsWith("\\\\.\\", StringComparison.Ordinal))
                        {
                            throw SQL.NonLocalSSEInstance();
                        }

                        if (null != pool)
                        { // Pooled connection - cache result
                            SqlConnectionPoolProviderInfo providerInfo = (SqlConnectionPoolProviderInfo)pool.ProviderInfo;
                            // No lock since we are already in creation mutex
                            providerInfo.InstanceName = instanceName;
                        }
                    }
                    finally
                    {
                        if (null != sseConnection)
                        {
                            sseConnection.Dispose();
                        }
                    }
                }
                else
                { // Cached info from pool.
                    SqlConnectionPoolProviderInfo providerInfo = (SqlConnectionPoolProviderInfo)pool.ProviderInfo;
                    // No lock since we are already in creation mutex
                    instanceName = providerInfo.InstanceName;
                }

                // NOTE: Here connection option opt is cloned to set 'instanceName=<UserInstanceName>' that was
                //       retrieved from the previous SSE connection. For this UserInstance connection 'Enlist=True'.
                // options immutable - stored in global hash - don't modify
                opt = new SqlConnectionString(opt, instanceName, userInstance: false, setEnlistValue: null);
                poolGroupProviderInfo = null; // null so we do not pass to constructor below...
            }
            return(new SqlInternalConnectionTds(identity, opt, key.Credential, poolGroupProviderInfo, "", null, redirectedUserInstance, userOpt, recoverySessionData, applyTransientFaultHandling: applyTransientFaultHandling, key.AccessToken, pool));
        }
Exemple #25
0
        internal DbConnectionInternal CreateNonPooledConnection(DbConnection owningConnection, DbConnectionPoolGroup poolGroup, DbConnectionOptions userOptions)
        {
            Debug.Assert(null != owningConnection, "null owningConnection?");
            Debug.Assert(null != poolGroup, "null poolGroup?");

            DbConnectionOptions connectionOptions = poolGroup.ConnectionOptions;
            DbConnectionPoolGroupProviderInfo poolGroupProviderInfo = poolGroup.ProviderInfo;
            DbConnectionPoolKey poolKey = poolGroup.PoolKey;

            DbConnectionInternal newConnection = CreateConnection(connectionOptions, poolKey, poolGroupProviderInfo, null, owningConnection, userOptions);

            if (null != newConnection)
            {
                PerformanceCounters.HardConnectsPerSecond.Increment();
                newConnection.MakeNonPooledObject(owningConnection, PerformanceCounters);
            }
            return(newConnection);
        }
Exemple #26
0
 public PendingGetConnection(long dueTime, DbConnection owner, TaskCompletionSource <DbConnectionInternal> completion, DbConnectionOptions userOptions)
 {
     DueTime    = dueTime;
     Owner      = owner;
     Completion = completion;
 }
 /// <devdoc>The default implementation is for the open connection objects, and
 /// it simply throws.  Our private closed-state connection objects
 /// override this and do the correct thing.</devdoc>
 // User code should either override DbConnectionInternal.Activate when it comes out of the pool
 // or override DbConnectionFactory.CreateConnection when the connection is created for non-pooled connections
 internal virtual bool TryOpenConnection(DbConnection outerConnection, DbConnectionFactory connectionFactory, TaskCompletionSource <DbConnectionInternal> retry, DbConnectionOptions userOptions)
 {
     throw ADP.ConnectionAlreadyOpen(State);
 }
Exemple #28
0
        private DbConnectionInternal CreateObject(DbConnection owningObject, DbConnectionOptions userOptions, DbConnectionInternal oldConnection)
        {
            DbConnectionInternal newObj = null;

            try
            {
                newObj = _connectionFactory.CreatePooledConnection(this, owningObject, _connectionPoolGroup.ConnectionOptions, _connectionPoolGroup.PoolKey, userOptions);
                if (null == newObj)
                {
                    throw ADP.InternalError(ADP.InternalErrorCode.CreateObjectReturnedNull);    // CreateObject succeeded, but null object
                }
                if (!newObj.CanBePooled)
                {
                    throw ADP.InternalError(ADP.InternalErrorCode.NewObjectCannotBePooled);        // CreateObject succeeded, but non-poolable object
                }
                newObj.PrePush(null);

                lock (_objectList)
                {
                    if ((oldConnection != null) && (oldConnection.Pool == this))
                    {
                        _objectList.Remove(oldConnection);
                    }
                    _objectList.Add(newObj);
                    _totalObjects = _objectList.Count;
                }

                // If the old connection belonged to another pool, we need to remove it from that
                if (oldConnection != null)
                {
                    var oldConnectionPool = oldConnection.Pool;
                    if (oldConnectionPool != null && oldConnectionPool != this)
                    {
                        Debug.Assert(oldConnectionPool._state == State.ShuttingDown, "Old connections pool should be shutting down");
                        lock (oldConnectionPool._objectList)
                        {
                            oldConnectionPool._objectList.Remove(oldConnection);
                            oldConnectionPool._totalObjects = oldConnectionPool._objectList.Count;
                        }
                    }
                }

                // Reset the error wait:
                _errorWait = ERROR_WAIT_DEFAULT;
            }
            catch (Exception e)
            {
                if (!ADP.IsCatchableExceptionType(e))
                {
                    throw;
                }
                newObj = null; // set to null, so we do not return bad new object
                // Failed to create instance
                _resError = e;

                // Make sure the timer starts even if ThreadAbort occurs after setting the ErrorEvent.

                // timer allocation has to be done out of CER block
                Timer t = new Timer(new TimerCallback(this.ErrorCallback), null, Timeout.Infinite, Timeout.Infinite);
                bool  timerIsNotDisposed;
                try { }
                finally
                {
                    _waitHandles.ErrorEvent.Set();
                    _errorOccurred = true;

                    // Enable the timer.
                    // Note that the timer is created to allow periodic invocation. If ThreadAbort occurs in the middle of ErrorCallback,
                    // the timer will restart. Otherwise, the timer callback (ErrorCallback) destroys the timer after resetting the error to avoid second callback.
                    _errorTimer        = t;
                    timerIsNotDisposed = t.Change(_errorWait, _errorWait);
                }

                Debug.Assert(timerIsNotDisposed, "ErrorCallback timer has been disposed");

                if (30000 < _errorWait)
                {
                    _errorWait = 60000;
                }
                else
                {
                    _errorWait *= 2;
                }
                throw;
            }
            return(newObj);
        }
        protected bool TryOpenConnectionInternal(DbConnection outerConnection, DbConnectionFactory connectionFactory, TaskCompletionSource <DbConnectionInternal> retry, DbConnectionOptions userOptions)
        {
            // ?->Connecting: prevent set_ConnectionString during Open
            if (connectionFactory.SetInnerConnectionFrom(outerConnection, DbConnectionClosedConnecting.SingletonInstance, this))
            {
                DbConnectionInternal openConnection = null;
                try {
                    connectionFactory.PermissionDemand(outerConnection);
                    if (!connectionFactory.TryGetConnection(outerConnection, retry, userOptions, this, out openConnection))
                    {
                        return(false);
                    }
                }
                catch {
                    // This should occure for all exceptions, even ADP.UnCatchableExceptions.
                    connectionFactory.SetInnerConnectionTo(outerConnection, this);
                    throw;
                }
                if (null == openConnection)
                {
                    connectionFactory.SetInnerConnectionTo(outerConnection, this);
                    throw ADP.InternalConnectionError(ADP.ConnectionError.GetConnectionReturnsNull);
                }
                connectionFactory.SetInnerConnectionEvent(outerConnection, openConnection);
            }

            return(true);
        }
Exemple #30
0
        internal bool TryGetConnection(DbConnection owningObject, TaskCompletionSource <DbConnectionInternal> retry, DbConnectionOptions userOptions, out DbConnectionInternal connection)
        {
            uint waitForMultipleObjectsTimeout = 0;
            bool allowCreate = false;

            if (retry == null)
            {
                waitForMultipleObjectsTimeout = (uint)CreationTimeout;

                // Set the wait timeout to INFINITE (-1) if the SQL connection timeout is 0 (== infinite)
                if (waitForMultipleObjectsTimeout == 0)
                {
                    waitForMultipleObjectsTimeout = unchecked ((uint)Timeout.Infinite);
                }

                allowCreate = true;
            }

            if (_state != State.Running)
            {
                connection = null;
                return(true);
            }

            bool onlyOneCheckConnection = true;

            if (TryGetConnection(owningObject, waitForMultipleObjectsTimeout, allowCreate, onlyOneCheckConnection, userOptions, out connection))
            {
                return(true);
            }
            else if (retry == null)
            {
                // timed out on a sync call
                return(true);
            }

            var pendingGetConnection =
                new PendingGetConnection(
                    CreationTimeout == 0 ? Timeout.Infinite : ADP.TimerCurrent() + ADP.TimerFromSeconds(CreationTimeout / 1000),
                    owningObject,
                    retry,
                    userOptions);

            _pendingOpens.Enqueue(pendingGetConnection);

            // it is better to StartNew too many times than not enough
            if (_pendingOpensWaiting == 0)
            {
                Thread waitOpenThread = new Thread(WaitForPendingOpen);
                waitOpenThread.IsBackground = true;
                waitOpenThread.Start();
            }

            connection = null;
            return(false);
        }
        private static void LoadStoreItemCollections(MetadataWorkspace workspace,
                                                     DbConnection storeConnection,
                                                     DbProviderFactory factory,
                                                     DbConnectionOptions connectionOptions,
                                                     EdmItemCollection edmItemCollection,
                                                     MetadataArtifactLoader artifactLoader)                                                     
        {
            Debug.Assert(workspace.IsItemCollectionAlreadyRegistered(DataSpace.CSpace), "C-Space must be loaded before loading S or C-S space");
                        
            // The provider connection string is optional; if it has not been specified,
            // we pick up the store's connection string.
            //
            string providerConnectionString = connectionOptions[EntityConnectionStringBuilder.ProviderConnectionStringParameterName];
            if (string.IsNullOrEmpty(providerConnectionString) && (storeConnection != null))
            {
                providerConnectionString = storeConnection.ConnectionString;
            }

            // Build a string as the key and look up the MetadataCache for a match
            string storeCacheKey = CreateMetadataCacheKey(artifactLoader.GetOriginalPaths(),
                                                          connectionOptions[EntityConnectionStringBuilder.ProviderParameterName],
                                                          providerConnectionString);

            // Load store metadata.
            object entryToken;
            StorageMappingItemCollection mappingCollection =
                MetadataCache.GetOrCreateStoreAndMappingItemCollections(storeCacheKey,
                                                                     artifactLoader,
                                                                     edmItemCollection,
                                                                     out entryToken);

            workspace.RegisterItemCollection(mappingCollection.StoreItemCollection);
            workspace.RegisterItemCollection(mappingCollection);

            // Adding the store metadata entry token to the workspace
            workspace.AddMetadataEntryToken(entryToken);
        }
Exemple #32
0
        private bool TryGetConnection(DbConnection owningObject, uint waitForMultipleObjectsTimeout, bool allowCreate, bool onlyOneCheckConnection, DbConnectionOptions userOptions, out DbConnectionInternal connection)
        {
            DbConnectionInternal obj = null;

            if (null == obj)
            {
                Interlocked.Increment(ref _waitCount);

                do
                {
                    int waitResult = BOGUS_HANDLE;
                    try
                    {
                        try
                        {
                        }
                        finally
                        {
                            waitResult = WaitHandle.WaitAny(_waitHandles.GetHandles(allowCreate), unchecked ((int)waitForMultipleObjectsTimeout));
                        }

                        // From the WaitAny docs: "If more than one object became signaled during
                        // the call, this is the array index of the signaled object with the
                        // smallest index value of all the signaled objects."  This is important
                        // so that the free object signal will be returned before a creation
                        // signal.

                        switch (waitResult)
                        {
                        case WaitHandle.WaitTimeout:
                            Interlocked.Decrement(ref _waitCount);
                            connection = null;
                            return(false);

                        case ERROR_HANDLE:
                            // Throw the error that PoolCreateRequest stashed.
                            Interlocked.Decrement(ref _waitCount);
                            throw TryCloneCachedException();

                        case CREATION_HANDLE:

                            try
                            {
                                obj = UserCreateRequest(owningObject, userOptions);
                            }
                            catch
                            {
                                if (null == obj)
                                {
                                    Interlocked.Decrement(ref _waitCount);
                                }
                                throw;
                            }
                            finally
                            {
                                // Ensure that we release this waiter, regardless
                                // of any exceptions that may be thrown.
                                if (null != obj)
                                {
                                    Interlocked.Decrement(ref _waitCount);
                                }
                            }

                            if (null == obj)
                            {
                                // If we were not able to create an object, check to see if
                                // we reached MaxPoolSize.  If so, we will no longer wait on
                                // the CreationHandle, but instead wait for a free object or
                                // the timeout.
                                if (Count >= MaxPoolSize && 0 != MaxPoolSize)
                                {
                                    if (!ReclaimEmancipatedObjects())
                                    {
                                        // modify handle array not to wait on creation mutex anymore
                                        Debug.Assert(2 == CREATION_HANDLE, "creation handle changed value");
                                        allowCreate = false;
                                    }
                                }
                            }
                            break;

                        case SEMAPHORE_HANDLE:
                            //
                            //    guaranteed available inventory
                            //
                            Interlocked.Decrement(ref _waitCount);
                            obj = GetFromGeneralPool();

                            if ((obj != null) && (!obj.IsConnectionAlive()))
                            {
                                DestroyObject(obj);
                                obj = null;         // Setting to null in case creating a new object fails

                                if (onlyOneCheckConnection)
                                {
                                    if (_waitHandles.CreationSemaphore.WaitOne(unchecked ((int)waitForMultipleObjectsTimeout)))
                                    {
                                        try
                                        {
                                            obj = UserCreateRequest(owningObject, userOptions);
                                        }
                                        finally
                                        {
                                            _waitHandles.CreationSemaphore.Release(1);
                                        }
                                    }
                                    else
                                    {
                                        // Timeout waiting for creation semaphore - return null
                                        connection = null;
                                        return(false);
                                    }
                                }
                            }
                            break;

                        default:
                            Interlocked.Decrement(ref _waitCount);
                            throw ADP.InternalError(ADP.InternalErrorCode.UnexpectedWaitAnyResult);
                        }
                    }
                    finally
                    {
                        if (CREATION_HANDLE == waitResult)
                        {
                            _waitHandles.CreationSemaphore.Release(1);
                        }
                    }
                } while (null == obj);
            }

            if (null != obj)
            {
                PrepareConnection(owningObject, obj);
            }

            connection = obj;
            return(true);
        }
        private static string ValidateValueForTheKeyword(
            DbConnectionOptions effectiveConnectionOptions,
            string keywordName)
        {
            var keywordValue = effectiveConnectionOptions[keywordName];
            if (!string.IsNullOrEmpty(keywordValue))
            {
                keywordValue = keywordValue.Trim(); // be nice to user, always trim the value
            }

            // Check that we have a non-null and non-empty value for the keyword
            if (string.IsNullOrEmpty(keywordValue))
            {
                throw new ArgumentException(Strings.EntityClient_ConnectionStringMissingInfo(keywordName));
            }
            return keywordValue;
        }
Exemple #34
0
        internal DbConnectionInternal CreatePooledConnection(DbConnectionPool pool, DbConnection owningObject, DbConnectionOptions options, DbConnectionPoolKey poolKey, DbConnectionOptions userOptions)
        {
            Debug.Assert(null != pool, "null pool?");
            DbConnectionPoolGroupProviderInfo poolGroupProviderInfo = pool.PoolGroup.ProviderInfo;

            DbConnectionInternal newConnection = CreateConnection(options, poolKey, poolGroupProviderInfo, pool, owningObject, userOptions);

            if (null != newConnection)
            {
                PerformanceCounters.HardConnectsPerSecond.Increment();
                newConnection.MakePooledConnection(pool);
            }
            SqlClientEventSource.Log.TryTraceEvent("<prov.DbConnectionFactory.CreatePooledConnection|RES|CPOOL> {0}, Pooled database connection created.", ObjectID);
            return(newConnection);
        }