protected override string GetDbProviderManifestToken(DbConnection connection)
        {
            EntityUtil.CheckArgumentNull(connection, "connection");

            SqlConnection sqlConnection = SqlProviderUtilities.GetRequiredSqlConnection(connection);

            if (string.IsNullOrEmpty(sqlConnection.ConnectionString))
            {
                throw EntityUtil.Argument(Strings.UnableToDetermineStoreVersion);
            }

            string providerManifestToken = null;

            // Try to get the provider manifest token from the database connection
            // That failing, try using connection to master database (in case the database doesn't exist yet)
            try
            {
                UsingConnection(sqlConnection, conn =>
                {
                    providerManifestToken = SqlVersionUtils.GetVersionHint(SqlVersionUtils.GetSqlVersion(conn));
                });
            }
            catch
            {
                UsingMasterConnection(sqlConnection, conn =>
                {
                    providerManifestToken = SqlVersionUtils.GetVersionHint(SqlVersionUtils.GetSqlVersion(conn));
                });
            }
            return(providerManifestToken);
        }
        /// <summary>
        /// Create the database and the database objects.
        /// If initial catalog is not specified, but AttachDBFilename is specified, we generate a random database name based on the AttachDBFilename.
        /// Note: this causes pollution of the db, as when the connection string is later used, the mdf will get attached under a different name.
        /// However if we try to replicate the name under which it would be attached, the following scenario would fail:
        ///    The file does not exist, but registered with database.
        ///    The user calls:  If (DatabaseExists) DeleteDatabase
        ///                     CreateDatabase
        /// For further details on the behavior when AttachDBFilename is specified see Dev10# 188936
        /// </summary>
        protected override void DbCreateDatabase(DbConnection connection, int?commandTimeout, StoreItemCollection storeItemCollection)
        {
            EntityUtil.CheckArgumentNull(connection, "connection");
            EntityUtil.CheckArgumentNull(storeItemCollection, "storeItemCollection");

            SqlConnection sqlConnection = SqlProviderUtilities.GetRequiredSqlConnection(connection);
            string        databaseName, dataFileName, logFileName;

            GetOrGenerateDatabaseNameAndGetFileNames(sqlConnection, out databaseName, out dataFileName, out logFileName);
            string     createDatabaseScript = SqlDdlBuilder.CreateDatabaseScript(databaseName, dataFileName, logFileName);
            SqlVersion sqlVersion           = GetSqlVersion(storeItemCollection);

            string createObjectsScript = CreateObjectsScript(sqlVersion, storeItemCollection);

            UsingMasterConnection(sqlConnection, conn =>
            {
                // create database
                CreateCommand(conn, createDatabaseScript, commandTimeout).ExecuteNonQuery();
            });

            // Create database already succeeded. If there is a failure from this point on, the user should be informed.
            try
            {
                // Clear connection pool for the database connection since after the 'create database' call, a previously
                // invalid connection may now be valid.
                SqlConnection.ClearPool(sqlConnection);

                UsingConnection(sqlConnection, conn =>
                {
                    // create database objects
                    CreateCommand(conn, createObjectsScript, commandTimeout).ExecuteNonQuery();
                });
            }
            catch (Exception e)
            {
                if (EntityUtil.IsCatchableExceptionType(e))
                {
                    // Try to drop the database
                    try
                    {
                        DropDatabase(sqlConnection, commandTimeout, databaseName);
                    }
                    catch (Exception ie)
                    {
                        // The creation of the database succeeded, the creation of the database objects failed, and the dropping of the database failed.
                        if (EntityUtil.IsCatchableExceptionType(ie))
                        {
                            throw new InvalidOperationException(Strings.SqlProvider_IncompleteCreateDatabase, new AggregateException(Strings.SqlProvider_IncompleteCreateDatabaseAggregate, e, ie));
                        }
                        throw;
                    }
                    // The creation of the database succeeded, the creation of the database objects failed, the database was dropped, no reason to wrap the exception
                    throw;
                }
                throw;
            }
        }
        /// <summary>
        /// Determines whether the database for the given connection exists.
        /// There are three cases:
        /// 1.  Initial Catalog = X, AttachDBFilename = null:   (SELECT Count(*) FROM sys.databases WHERE [name]= X) > 0
        /// 2.  Initial Catalog = X, AttachDBFilename = F:      if (SELECT Count(*) FROM sys.databases WHERE [name]= X) >  true,
        /// if not, try to open the connection and then return (SELECT Count(*) FROM sys.databases WHERE [name]= X) > 0
        /// 3.  Initial Catalog = null, AttachDBFilename = F:   Try to open the connection. If that succeeds the result is true, otherwise
        /// if the there are no databases corresponding to the given file return false, otherwise throw.
        ///
        /// Note: We open the connection to cover the scenario when the mdf exists, but is not attached.
        /// Given that opening the connection would auto-attach it, it would not be appropriate to return false in this case.
        /// Also note that checking for the existence of the file does not work for a remote server.  (Dev11 #290487)
        /// For further details on the behavior when AttachDBFilename is specified see Dev10# 188936
        /// </summary>
        protected override bool DbDatabaseExists(DbConnection connection, int?commandTimeout, StoreItemCollection storeItemCollection)
        {
            EntityUtil.CheckArgumentNull(connection, "connection");
            EntityUtil.CheckArgumentNull(storeItemCollection, "storeItemCollection");

            SqlConnection sqlConnection     = SqlProviderUtilities.GetRequiredSqlConnection(connection);
            var           connectionBuilder = new SqlConnectionStringBuilder(sqlConnection.ConnectionString);

            if (string.IsNullOrEmpty(connectionBuilder.InitialCatalog) && string.IsNullOrEmpty(connectionBuilder.AttachDBFilename))
            {
                throw EntityUtil.InvalidOperation(Strings.SqlProvider_DdlGeneration_MissingInitialCatalog);
            }

            if (!string.IsNullOrEmpty(connectionBuilder.InitialCatalog))
            {
                if (CheckDatabaseExists(sqlConnection, commandTimeout, connectionBuilder.InitialCatalog))
                {
                    //Avoid further processing
                    return(true);
                }
            }

            if (!string.IsNullOrEmpty(connectionBuilder.AttachDBFilename))
            {
                try
                {
                    UsingConnection(sqlConnection, (SqlConnection con) => { });
                    return(true);
                }
                catch (SqlException e)
                {
                    if (!string.IsNullOrEmpty(connectionBuilder.InitialCatalog))
                    {
                        return(CheckDatabaseExists(sqlConnection, commandTimeout, connectionBuilder.InitialCatalog));
                    }
                    // Initial catalog not specified
                    string fileName = GetMdfFileName(connectionBuilder.AttachDBFilename);
                    bool   databaseDoesNotExistInSysTables = false;
                    UsingMasterConnection(sqlConnection, conn =>
                    {
                        SqlVersion sqlVersion       = SqlVersionUtils.GetSqlVersion(conn);
                        string databaseExistsScript = SqlDdlBuilder.CreateCountDatabasesBasedOnFileNameScript(fileName, useDeprecatedSystemTable: sqlVersion == SqlVersion.Sql8);
                        int result = (int)CreateCommand(conn, databaseExistsScript, commandTimeout).ExecuteScalar();
                        databaseDoesNotExistInSysTables = (result == 0);
                    });
                    if (databaseDoesNotExistInSysTables)
                    {
                        return(false);
                    }
                    throw EntityUtil.InvalidOperation(Strings.SqlProvider_DdlGeneration_CannotTellIfDatabaseExists, e);
                }
            }

            // CheckDatabaseExists returned false and no AttachDBFilename is specified
            return(false);
        }
        /// <summary>
        /// Delete the database for the given connection.
        /// There are three cases:
        /// 1.  If Initial Catalog is specified (X) drop database X
        /// 2.  Else if AttachDBFilename is specified (F) drop all the databases corresponding to F
        /// if none throw
        /// 3.  If niether the catalog not the file name is specified - throw
        ///
        /// Note that directly deleting the files does not work for a remote server.  However, even for not attached
        /// databases the current logic would work assuming the user does: if (DatabaseExists) DeleteDatabase
        /// </summary>
        /// <param name="connection"></param>
        /// <param name="commandTimeout"></param>
        /// <param name="storeItemCollection"></param>
        protected override void DbDeleteDatabase(DbConnection connection, int?commandTimeout, StoreItemCollection storeItemCollection)
        {
            EntityUtil.CheckArgumentNull(connection, "connection");
            EntityUtil.CheckArgumentNull(storeItemCollection, "storeItemCollection");
            SqlConnection sqlConnection = SqlProviderUtilities.GetRequiredSqlConnection(connection);

            var    connectionBuilder = new SqlConnectionStringBuilder(sqlConnection.ConnectionString);
            string initialCatalog    = connectionBuilder.InitialCatalog;
            string attachDBFile      = connectionBuilder.AttachDBFilename;

            if (!string.IsNullOrEmpty(initialCatalog))
            {
                DropDatabase(sqlConnection, commandTimeout, initialCatalog);
            }

            // initial catalog not specified
            else if (!string.IsNullOrEmpty(attachDBFile))
            {
                string fullFileName = GetMdfFileName(attachDBFile);

                List <string> databaseNames = new List <string>();
                UsingMasterConnection(sqlConnection, conn =>
                {
                    SqlVersion sqlVersion         = SqlVersionUtils.GetSqlVersion(conn);
                    string getDatabaseNamesScript = SqlDdlBuilder.CreateGetDatabaseNamesBasedOnFileNameScript(fullFileName, sqlVersion == SqlVersion.Sql8);
                    var command = CreateCommand(conn, getDatabaseNamesScript, commandTimeout);
                    using (var reader = command.ExecuteReader())
                    {
                        while (reader.Read())
                        {
                            databaseNames.Add(reader.GetString(0));
                        }
                    }
                });
                if (databaseNames.Count > 0)
                {
                    foreach (var databaseName in databaseNames)
                    {
                        DropDatabase(sqlConnection, commandTimeout, databaseName);
                    }
                }
                else
                {
                    throw EntityUtil.InvalidOperation(Strings.SqlProvider_DdlGeneration_CannotDeleteDatabaseNoInitialCatalog);
                }
            }
            // neither initial catalog nor attachDB file name are specified
            else
            {
                throw EntityUtil.InvalidOperation(Strings.SqlProvider_DdlGeneration_MissingInitialCatalog);
            }
        }