在C#中创建(按需)SQL Server 2008 Express数据库的最佳实践?

时间:2010-02-27 20:26:51

标签: c# sql-server winforms ado.net sql-server-express

目的是在全新的SQL Server 2008 Express数据库中处理用户的数据(您可以将其称为项目,文档,文件或其他内容)。预计这些数据所占用的空间将远远少于快递版本提供的4GB空间(也可免费分发)。

,例如,每次用户选择File-> New命令时,将在指定位置创建一个新的空数据库。另一方面,类似的命令File-> Open必须提供支持以检索数据库列表以选择一个用于打开的数据库。

因此,必须解决以下问题: a)应用程序必须能够创建连接字符串并通过代码将数据库附加到SQL Server 2008 Express(C#) b)应用程序必须能够(再次通过代码)检索包含所有可用数据库的列表,以便用户有机会选择一个打开。

我认为在资源中使用模板数据库并将其复制到用户指定的位置会很有帮助。

您认为这是一个有效的解决方案吗?你有什么建议吗?

6 个答案:

答案 0 :(得分:16)

你可以使用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 :(得分:1)

另一种解决方案是使用SQLite而不是SQL Express。如果使用this solution,甚至可以继续使用ADO.NET。 SQLite数据库只是文件,您的连接字符串可以引用文件路径。当用户想要打开他们的文件时,他们可以选择一个实际的文件。

答案 2 :(得分:1)

我得到的印象是这个数据库将在用户的机器上本地生存。如果是这种情况,sql server express通常不是一个很好的数据库选择。它是服务器级引擎,而不是桌面或流程引擎。相反,您可以使用许多优秀的流程引擎:Sql Server Compact Edition,Sqlite(如Jacob所述)甚至是Access。

答案 3 :(得分:1)

如果您认为SQL Server Express 2008是正确的选择(尽管sqllite看起来确实更合适),我会考虑使用User Instances,这将允许非管理员在您描述的文件中添加数据库。

答案 4 :(得分:1)

本文介绍如何创建新数据库,并将其附加到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

答案 5 :(得分:0)

对于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身份验证。