首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
您现在的位置: 程式碼之家 >> 編程語言 >  >> .NET 網頁程式設計 >> 關於.NET

LINQS 0.0.6 實戰:領域模型描述數據庫並生成建庫腳本與物理庫

     編輯:關於.NET

LINQS (Language INtegrated Query for Schema) 是一個以 C# 語法**強類型描述數據庫模型**,並能生成 SQL 建庫腳本、直接操作 SQL Server Express 建立物理庫的工具庫。本文演示 0.0.6 版核心流程:模型描述 → 腳本生成 → 物理建庫。

核心命名空間

  • `Xbb.Data.SqlServerModel.Katmai`:SQL Server 2008 模型描述類型 (`Table`, `Column`, `Database`, `AssociationColumn`...)
  • `Xbb.Data.SqlServerModel.Katmai.Script.Create`:模型 → SQL 腳本生成服務。
  • `Xbb.Data.SqlServerModel.Katmai.Physical`:操作本地 SQL Express 物理庫 (`ExpressDatabase`)。

步驟一:描述名片數據庫模型 (強類型 C#)

// 引用 Katmai 命名空間
var profession = new Table {
    Name = "Profession",
    Columns = new IColumn[] {
        new Column { Name = "Name", Type = new NVarChar(50) }
    }
};

var db = new Database {
    Name = "NameCards",
    Tables = new Table[] {
        new Table {
            Name = "Person",
            Columns = new IColumn[] {
                new Column { Name = "Name", Type = new NVarChar(50) },
                new Column { Name = "Age", Type = new Int() },
                new AssociationColumn { Name = "ProfessionID", Table = profession } // 外鍵關聯
            }
        },
        profession
    }
};

步驟二:補全系統列 (ID/RowGuid/ModifiedDate)

foreach (var t in db.Tables) {
    if (t.PrimaryKey == null) {
        var id = new IdentityColumn(t.Name + "ID"); // 自增主鍵
        t.Columns = new Column[] { id }.Concat(t.Columns);
        t.IdentityColumn = id;
        t.PrimaryKey = new IColumn[] { id };
        t.Keys = new IEnumerable<IColumn>[] { t.PrimaryKey };
    }
    var rowGuid = new RowGuidColumn();       // uniqueidentifier
    var modifiedDate = new ModifiedDateColumn(); // datetime, 默認 getdate()
    t.RowGuidColumn = rowGuid;
    t.Columns = t.Columns.Concat(new Column[] { rowGuid, modifiedDate });
}

這對應 SSMS **Database Diagram** 中的完整對象結構,比純 SQL 腳本更豐富 (標識 Identity/RowGuid/ModifiedDate 語義)。

步驟三:生成建庫 SQL 腳本

string script = new Script.Create.Database(db).ToString();

輸出片段:

CREATE TABLE [Person](
  [PersonID] Int NOT NULL IDENTITY,
  [Name] NVarChar(50) NOT NULL,
  [Age] Int NOT NULL,
  [ProfessionID] Int NOT NULL,
  [rowguid] UniqueIdentifier NOT NULL,
  [ModifiedDate] DateTime NOT NULL,
  CONSTRAINT [PK_Person_1] PRIMARY KEY CLUSTERED ([PersonID] ASC) ...
)
CREATE TABLE [Profession]( ... )
ALTER TABLE [Person] ADD CONSTRAINT [FK_Person_Profession_ProfessionID] 
  FOREIGN KEY ([ProfessionID]) REFERENCES [Profession]([ProfessionID]) ...

步驟四:直接創建物理數據庫 (SQL Express)


string name = "AdventureWorks2008";
string folder = @"C:\MyDbs"; // 必須有寫入權限
string mdfPath = Path.Combine(folder, name + ".mdf");

using (var physical = ExpressDatabase.Create(
    name, mdfPath, true, 
    OnDisposeTask.DetachDatabaseAndKeepFiles)) {
    physical.RunScript(script, null);
}
  • `ExpressDatabase.Create`:建立/連接 SQL Express 實例,附加 MDF 文件。
  • `OnDisposeTask.DetachDatabaseAndKeepFiles`:釋放時分離庫但保留文件。
  • `RunScript`:批次執行生成的 SQL 腳本。

源碼參考路徑

  • 模型描述範例:`_Katmai\Katmai\Katmai\Descriptor\Sample.cs`
  • 腳本生成測試:`_Katmai\KatmaiTest\KatmaiTest\ScriptTest.cs`
  • 物理庫操作測試:`_Katmai.Physical\Katmai.Physical.Test\Katmai.Physical.Test\ExpressDatabaseTest.cs`

設計亮點

  1. 模型即代碼:C# 類型系統驗證模型正確性 (編譯期捕獲拼寫錯誤、類型不匹配)。
  2. 關聯語義化:`AssociationColumn` 直接引用 `Table` 物件,而非字串名稱 — 重構安全。
  3. 系統列標準化:Identity/RowGuid/ModifiedDate 統一約定,自動生成約束與默認值。
  4. 腳本與物理分離:先生成腳本可審查/版控,再決定是否執行建庫。

適用場景

  • 代碼優先 開發,需版本控制 Schema 變更。
  • 測試環境自動化佈署 (CI/CD 階段建庫)。
  • 產品安裝程序內嵌建庫邏輯 (無需分發 .sql 文件)。

LINQS 展示了「Schema as Code」的工程化價值 — 讓數據庫結構享受與業務代碼同等的重構、測試、版控待遇。

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