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

发布于 2024-08-23 04:26:56 字数 430 浏览 6 评论 0 原文

目的是在全新的 SQL Server 2008 Express 数据库中处理用户的数据(您可以将它们称为项目、文档、文件或其他任何名称)。这些数据预计占用的空间比 Express 版本(也是免费分发)的 4GB 可用空间少得多。

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

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

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

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

The purpose is to handle the user's data (you can call them project, document, file, or whatever) in a brand new SQL Server 2008 Express database. The data are expected to occupy much less space than the 4GB available with the express edition (which is also free to distribute).

E.g., each time the user selects File->New command, a new empty database will be created at the specified location. On the other hand, a similar command, File->Open must provide support to retrieve the list of the databases to select one for opening.

So, the following issues must be resolved:
a) The application must be able to create the connection string and attach the database to SQL Server 2008 Express through code (C#)
b) The application must be able to retrieve (again through code) a list with all the available databases, to give the user a chance to select one to open.

I think it would be helpful to have a template database in resources and copy it in the location specified by the user.

Do you think it is a working solution? Do you have any suggestions?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(6

木緿 2024-08-30 04:26:56

您可以使用 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;
    }

}

There's lots you can do with Sql Server Management Objects (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;
    }

}
李白 2024-08-30 04:26:56

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

An alternate solution is to use SQLite rather than SQL Express. You can even continue to use ADO.NET if you use this solution. SQLite databases are simply files, and your connection strings can refer to the file path. When a user wants to open their file, they can select an actual file.

揪着可爱 2024-08-30 04:26:56

我的印象是该数据库将驻留在用户本地计算机上。如果是这种情况,SQL Server Express 通常不是一个好的数据库选择。它是一个服务器级引擎,而不是桌面或进程内引擎。相反,您可以使用许多优秀的流程引擎:Sql Server Compact Edition、Sqlite(正如 Jacob 所提到的)甚至 Access。

I get the impression that this database will live locally on user's machine. If that's the case, sql server express is not usually a good database choice. It's a server-class engine rather than a desktop or in process engine. Instead, there are a number of good in process engines you can use: Sql Server Compact Edition, Sqlite (as mentioned by Jacob) or even Access.

北城挽邺 2024-08-30 04:26:56

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

If you believe SQL Server Express 2008 is the right choice (sqllite does seem to fit better though), I would look at using User Instances which will allow non-administrators to add databases from files as you describe.

淡淡の花香 2024-08-30 04:26:56

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

This article shows how to create a new database, and attach it to a SQL Server database instance:

How to: Attach a Database File to SQL Server Express
http://msdn.microsoft.com/en-us/library/ms165673.aspx

These article shows how to manage the attaching and detaching of existing databases:
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

月牙弯弯 2024-08-30 04:26:56

对于 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认证。

For the following connection string for SQL Server 2008 R2.

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

you can do

  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;
  }

Thanks to Mr. Harvey for pointing the right direction. Although in my case, I have to make these small changes. Because, I use the windows authentication.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文