首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
您现在的位置: 程式碼之家 >> 數據庫知識 >  >> DB2 資料庫 >> DB2 教學

.NET 安裝包集成:自動創建 SQL Server 數據庫與表結構的 Custom Action 開發全流程

     編輯:DB2 教學

業務背景:零接觸部署的數據庫初始化需求

企業級應用分發時,往往需要在客戶環境「無感知」完成數據庫創建、Schema 初始化、基礎數據植入。利用 Visual Studio Setup Project + Installer Class 自定義動作,可將此邏輯封裝進 MSI,實現安裝向導中輸入數據庫名 → 靜默完成建庫建表。

架構設計:三層解耦

  1. 資源層: SQL 腳本嵌入為 Embedded Resource (sql.txt),版本隨代碼管理
  2. 邏輯層: DBCustomAction.cs 繼承 System.Configuration.Install.Installer,實現 Install() 重寫
  3. 表現層: 安裝向導對話框收集參數 → CustomActionData 傳遞給邏輯層

核心代碼實現

1. 讀取嵌入資源 SQL 腳本

private string GetSql(string resourceName) {
    Assembly asm = Assembly.GetExecutingAssembly();
    using (Stream strm = asm.GetManifestResourceStream(asm.GetName().Name + "." + resourceName))
    using (StreamReader reader = new StreamReader(strm))
        return reader.ReadToEnd();
}

2. 執行 SQL 批次(支援切換數據庫上下文)

private void ExecuteSql(string databaseName, string sql) {
    using (var conn = new SqlConnection(GetMasterConnectionString()))
    using (var cmd = new SqlCommand(sql, conn)) {
        conn.Open();
        cmd.CommandTimeout = 300; // 大腳本防超時
        if (!string.Equals(databaseName, "master", StringComparison.OrdinalIgnoreCase))
            cmd.ExecuteNonQuery($"USE [{databaseName}]");
        cmd.ExecuteNonQuery();
    }
}

3. 安裝入口:創建數據庫 → 執行 Schema 腳本

protected void AddDBTable(string dbName) {
    try {
        // 1. 在 master 中創建用戶數據庫
        ExecuteSql("master", $"CREATE DATABASE [{dbName}]");
        // 2. 切換至新庫執行建表腳本
        ExecuteSql(dbName, GetSql("sql.txt"));
    } catch (Exception ex) {
        // 安裝日誌記錄,拋出讓 MSI 回滾
        Context.LogMessage($"DB 初始化失敗: {ex.Message}");
        throw;
    }
}

public override void Install(IDictionary stateSaver) {
    base.Install(stateSaver);
    string dbName = Context.Parameters["dbname"]; // 從 CustomActionData 獲取
    if (string.IsNullOrWhiteSpace(dbName))
        throw new ArgumentException("數據庫名不能為空");
    AddDBTable(dbName);
}

SQL 腳本規範 (sql.txt 嵌入資源)

CREATE TABLE [dbo].[MK_Employees] (
    [Name] [char](30) COLLATE SQL_Latin1_General_CP1_CI_AS NOT NULL,
    [Rsvp] [int] NULL,
    [Requests] [nvarchar](4000) COLLATE SQL_Latin1_General_CP1_CI_AS NULL
) ON [PRIMARY];

ALTER TABLE [dbo].[MK_Employees] WITH NOCHECK ADD
CONSTRAINT [PK_MK_Employees] PRIMARY KEY CLUSTERED ([Name]) ON [PRIMARY];

提示: 可用 SSMS「生成腳本」導出完整 Schema,保存為 sql.txt,屬性設置 Build Action = Embedded Resource。

安裝向導 UI 定制:收集數據庫名參數

  1. Setup Project → View → User Interface → Start 节點 → Add Dialog → Textboxes (A)
  2. 移至頂層,屬性配置:
    • BannerText: "指定數據庫名稱"
    • BodyText: "請輸入要在數據庫服務器上創建的數據庫名稱"
    • Edit1Label: "數據庫名", Edit1Property: CUSTOMTEXTA1
    • Edit2/3/4 Visible = False

Custom Action 綁定參數傳遞

  1. View → Custom Actions → Install 節點 → Add → Application Folder → Primary Output (DBCustomAction)
  2. 該 Output 屬性 CustomActionData = /dbname=[CUSTOMTEXTA1]
  3. 對應代碼中 Context.Parameters["dbname"] 獲取

進階增強:生產級健壯性考量

場景解決方案
數據庫已存在腳本加 IF NOT EXISTS (SELECT * FROM sys.databases WHERE name=@name) CREATE DATABASE ...
權限不足安裝前檢測 sysadmin 角色,或提示使用 Windows 驗證/指定高權限賬號
大腳本超時cmd.CommandTimeout = 0 (無限) 或分批執行 GO 批次
協議/實例名連接字串支持 Server=.\SQLEXPRESS;Integrated Security=SSPI 等多格式
回滾支持實現 Uninstall() 刪除數據庫,或標記 Rollback 腳本
日誌審計寫入 Windows Event Log 或安裝目錄 Install.log

替代方案對比

  • WiX Toolset: 純 XML 定義,支持複雜條件、服務控制、更適合 CI/CD
  • PowerShell + Chocolatey/Scoop: 腳本化部署,版本管理更靈活
  • Docker/容器化: 數據庫遷移腳本 (Flyway/Liquibase) 內建鏡像,現代化首選

結語

VS Setup Project 雖屬經典技術,但在存量系統維護、簡單分發場景仍具實用價值。關鍵在於「資源嵌入 + 參數化執行 + UI 參數收集」三步閉環,並做好異常處理與回滾。新項目建議直接採用 Flyway/Liquibase + 容器化部署,實現 Schema 版本化與零停機遷移。

  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved