代码之家  ›  专栏  ›  技术社区  ›  ileon

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

  •  5
  • ileon  · 技术社区  · 14 年前

    其目的是在一个全新的SQL Server 2008 Express数据库中处理用户的数据(您可以将其称为项目、文档、文件或其他内容)。预计这些数据所占用的空间将比Express Edition(也可以免费分发)提供的4GB少得多。

    例如,每次用户选择“文件”->new命令时,将在指定位置创建新的空数据库。另一方面,类似的命令file->open必须提供检索数据库列表的支持,以便选择一个数据库进行打开。

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

    我认为在参考资料中建立一个模板数据库并将其复制到用户指定的位置会很有帮助。

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

    6 回复  |  直到 7 年前
        1
  •  16
  •   Robert Harvey    14 年前

    使用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;
        }
    
    }
    
        2
  •  1
  •   Jacob    14 年前

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

        3
  •  1
  •   Joel Coehoorn    14 年前

    我觉得这个数据库将在本地用户的计算机上运行。如果是这样,SQL Server Express通常不是一个好的数据库选择。它是一个服务器类引擎,而不是桌面或进程内引擎。相反,您可以使用许多好的进程内引擎:SQL Server Compact Edition、SQLite(如Jacob所述)甚至Access。

        4
  •  1
  •   bkaid    14 年前

    如果您认为SQL Server Express 2008是正确的选择(不过,sqllite似乎更适合),我会考虑使用 User Instances 这将允许非管理员根据您的描述从文件添加数据库。

        5
  •  1
  •   Robert Harvey    14 年前

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

        6
  •  0
  •   jero2rome    10 年前

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