DataContext 是 LINQ to SQL 的主要進入點,提供資料庫連線管理、查詢執行、變更追蹤與提交等核心功能。
透過實體類別定義結構,呼叫 CreateDatabase() 可依定義自動建立資料庫;DeleteDatabase() 則移除之。資料庫命名優先序:連接字串指定 > [Database] 屬性 > 強型別 DataContext 類別名 > .mdf 檔名。
// 定義實體與 DataContext
public class NewCreateDB : DataContext {
public Table<Person> Persons;
public NewCreateDB(string conn) : base(conn) { }
}
[Table(Name = "Person")]
public partial class Person {
[Column(IsPrimaryKey = true, IsDbGenerated = true)] public int PersonID { get; set; }
[Column(DbType = "NVarChar(30)")] public string PersonName { get; set; }
[Column(DbType = "INT")] public int? Age { get; set; }
}
// 使用流程
string folder = Environment.GetEnvironmentVariable("SystemDrive") + @"\YJingLee";
Directory.CreateDirectory(folder);
string mdf = Path.Combine(folder, "NewCreateDB.mdf");
string connStr = $@"Data Source=.\SQLEXPRESS;AttachDbFilename={mdf};Integrated Security=True;User Instance=True;";
NewCreateDB newDB = new NewCreateDB(connStr);
newDB.CreateDatabase(); // 建立資料庫
newDB.Persons.InsertOnSubmit(new Person { PersonID = 1, PersonName = "YJingLee", Age = 22 });
newDB.SubmitChanges(); // 提交插入
var q = from x in newDB.Persons select x; // 查詢驗證
newDB.DeleteDatabase(); // 刪除資料庫
Directory.Delete(folder); // 清理資料夾
if (db.DatabaseExists()) Console.WriteLine("Northwind 存在");
NewCreateDB newDB = new NewCreateDB(mdfPath);
if (newDB.DatabaseExists()) Console.WriteLine("NewCreateDB 存在");
SubmitChanges() 會計算所有異動、依相依性排序、開啟交易、逐筆轉換 SQL 送往伺服器。若發生錯誤則回滾,DataContext 仍保留異動紀錄供重試。
// 隱式事務:SubmitChanges 內部自動建立
try {
Product p1 = db.Products.First(p => p.ProductID == 4);
Product p2 = db.Products.First(p => p.ProductID == 5);
p1.UnitsInStock -= 3;
p2.UnitsInStock -= 5; // 違反 CHECK 約束導致失敗
db.SubmitChanges(); // 全部回滾
} catch (SqlException e) { /* 處理 */ }
// 顯式事務:使用 TransactionScope
using (TransactionScope ts = new TransactionScope()) {
try {
// 同樣的異動操作
db.SubmitChanges();
ts.Complete(); // 明確完成
} catch { /* 處理 */ }
}
DataContext 亦可搭配運算式樹進行動態查詢(詳見前篇);Log 屬性可將生成 SQL 輸出至 Console.Out 或 StreamWriter,極利除錯。
db.Log = Console.Out; // 輸出至主控台
var q = from c in db.Customers where c.City == "London" select c;
StreamWriter sw = new StreamWriter("log.txt", true);
db.Log = sw; // 輸出至檔案
// ... 查詢操作
sw.Close();