Как создать (по требованию) базы данных SQL Server 2008 Express в C #? - PullRequest
5 голосов
/ 27 февраля 2010

Целью является обработка данных пользователя (вы можете назвать их проектом, документом, файлом или чем-то еще) в новой базе данных SQL Server 2008 Express. Ожидается, что данные будут занимать гораздо меньше места, чем 4 ГБ, доступные в экспресс-выпуске (который также можно свободно распространять).

Например, каждый раз, когда пользователь выбирает команду Файл-> Новая, в указанном месте будет создаваться новая пустая база данных. С другой стороны, аналогичная команда File-> Open должна обеспечивать поддержку для получения списка баз данных, чтобы выбрать одну для открытия.

Итак, необходимо решить следующие проблемы: а) Приложение должно иметь возможность создавать строку подключения и присоединять базу данных к SQL Server 2008 Express с помощью кода (C #) b) Приложение должно иметь возможность извлекать (снова через код) список со всеми доступными базами данных, чтобы дать пользователю возможность выбрать одну для открытия.

Я думаю, что было бы полезно иметь базу данных шаблонов в ресурсах и копировать ее в место, указанное пользователем.

Как вы думаете, это рабочее решение? У вас есть предложения?

Ответы [ 6 ]

16 голосов
/ 28 февраля 2010

Вы можете многое сделать с объектами управления Sql Server (SMO):

// Add a reference to Microsoft.SqlServer.Smo
// Add a reference to Microsoft.SqlServer.ConnectionInfo
// Add a reference to Microsoft.SqlServer.SqlEnum

using Microsoft.SqlServer.Management.Smo;
using System.Collections.Generic;
using System.Collections.Specialized;
using System.Data;

public class SqlServerController
{

    private Server m_server = null;

    public SqlServerController(string server)
    {
        m_server = new Server(server);
    }

    public void AttachDatabase(string database, StringCollection files,
        AttachOptions options)
    {
        m_server.AttachDatabase(database, files, options);
    }

    public void AddBackupDevice(string name)
    {
        BackupDevice device = new BackupDevice(m_server, name);
        m_server.BackupDevices.Add(device);
    }

    public string GetServerVersion(string serverName)
    {
        return m_server.PingSqlServerVersion(serverName).ToString();
    }

    public int CountActiveConnections(string database)
    {
        return m_server.GetActiveDBConnectionCount(database);
    }

    public void DeleteDatabase(string database)
    {
        m_server.KillDatabase(database);
    }

    public void DetachDatabase(string database, bool updateStatistics, 
        bool removeFullTextIndex)
    {
        m_server.DetachDatabase(database, updateStatistics, removeFullTextIndex);
    }

    public void CreateDatabase(string database)
    {
        Database db = new Database(m_server, database);
        db.Create();
    }

    public void CreateTable(string database, string table, 
        List<Column> columnList, List<Index> indexList)
    {
        Database db = m_server.Databases[database];
        Table newTable = new Table(db, table);

        foreach (Column column in columnList)
            newTable.Columns.Add(column);

        if (indexList != null)
        {
            foreach (Index index in indexList)
                newTable.Indexes.Add(index);
        }

        newTable.Create();

    }

    public Column CreateColumn(string name, DataType type, string @default,
        bool isIdentity, bool nullable)
    {
        Column column = new Column();

        column.DataType = type;
        column.Default = @default;
        column.Identity = isIdentity;
        column.Nullable = nullable;

        return column;
    }

    public Index CreateIndex(string name, bool isClustered, IndexKeyType type,
      string[] columnNameList)
    {

        Index index = new Index();

        index.Name = name;
        index.IndexKeyType = type;
        index.IsClustered = isClustered;

        foreach (string columnName in columnNameList)
            index.IndexedColumns.Add(new IndexedColumn(index, columnName));

        return index;
    }

}
1 голос
/ 28 февраля 2010

В этой статье показано, как создать новую базу данных и подключить ее к экземпляру базы данных SQL Server:

Как: прикрепить файл базы данных к SQL Server Express
http://msdn.microsoft.com/en-us/library/ms165673.aspx

В этой статье показано, как управлять подключением и отключением существующих баз данных: http://msdn.microsoft.com/en-us/library/ms190794.aspx

http://www.databasejournal.com/features/mssql/article.php/2224361/Attaching-and-Detaching-Databases-on-SQL-Server.htm

1 голос
/ 27 февраля 2010

Если вы считаете, что SQL Server Express 2008 является правильным выбором (sqllite, кажется, все же подходит лучше), я бы посмотрел на использование пользовательских экземпляров , которые позволят неадминистраторам добавлять базы данных из файлов, когда вы описать.

1 голос
/ 27 февраля 2010

У меня сложилось впечатление, что эта база данных будет жить локально на компьютере пользователя. В этом случае SQL Server Express обычно не является хорошим выбором для базы данных. Это движок серверного класса, а не рабочий стол или процессор. Вместо этого вы можете использовать ряд хороших процессоров: Sql Server Compact Edition, Sqlite (как упомянуто Джейкобом) или даже Access.

1 голос
/ 27 февраля 2010

Альтернативным решением является использование SQLite, а не SQL Express. Вы даже можете продолжать использовать ADO.NET, если используете это решение . Базы данных SQLite - это просто файлы, и ваши строки подключения могут ссылаться на путь к файлу. Когда пользователь хочет открыть свой файл, он может выбрать фактический файл.

0 голосов
/ 10 марта 2014

Для следующей строки подключения для SQL Server 2008 R2.

   <connectionstring>Data Source=.\SQLEXPRESS;Initial Catalog=MyDatabase;Integrated Security=True;Pooling=True</connectionstring>

вы можете сделать

  var connectionString = new SqlConnectionStringBuilder(connectionString);

  var serverConnection = new ServerConnection("DatabaseInstanceName in server");

  var serverInstance = new Server(serverConnection);

  if (serverInstance.Databases.Contains(connectionString.InitialCatalog))
      serverInstance.KillDatabase(connectionString.InitialCatalog);

  var db = new Database(serverInstance, connectionString.InitialCatalog);

  try
  {
     db.Create();
  }
  catch (SqlException ex)
  {
     throw;
  }

Спасибо мистеру Харви за то, что он указал верное направление. Хотя в моем случае я должен сделать эти небольшие изменения. Потому что я использую аутентификацию Windows.

...