承接上篇,本文深入探討 LINQ to SQL 中如何以自訂存儲程序覆寫自動生成的 CRUD 方法,並提出資料存取層 (DAL) 的具體實作方案,解決實體類別與資料庫操作的解耦問題。
將資料表拖入 O/R 設計器後,LINQ 自動生成 Insert/Update/Delete 方法。實務上常需自訂邏輯(如觸發審計、複雜業務規則),此時需對應存儲程序:
ENTUserAccountInsert)。Insert、Update、Delete 對應的存儲程序。CREATE PROCEDURE ENTUserAccountInsert
(
@WindowsAccountName varchar(50),
@FirstName varchar(50),
@LastName varchar(50),
@Email varchar(100),
@IsActive bit,
@InsertENTUserAccountId int
)
AS
SET NOCOUNT ON
INSERT INTO ENTUserAccount(WindowsAccountName, FirstName, LastName,
Email, IsActive, InsertENTUserAccountId, InsertDate,
UpdateENTUserAccountId, UpdateDate)
VALUES (@WindowsAccountName, @FirstName, @LastName, @Email,
@IsActive, @InsertENTUserAccountId, GetDate(),
@InsertENTUserAccountId, GetDate())
RETURN
| 方案 | 優點 | 缺點 | 適用場景 |
|---|---|---|---|
| ADO.NET 直寫 (SqlCommand 等) | 彈性最高、效能最好 | 樣板代碼多、維護成本高 | 高效能、特殊 SQL 需求 |
| SqlHelper (Microsoft Data Access Application Block) | 封裝常用執行方法、減少重複代碼 | 仍需撰寫 SQL、參數管理手動 | 中小型專案、團隊熟悉 ADO.NET |
| LINQ to SQL | 強型別、IntelliSense、自動追蹤變更、支援存儲程序自訂 | 僅支援 SQL Server、大型複雜查詢效能較弱 | 企業級專案、領域模型導向 |
| Entity Framework (Core) | 跨資料庫、成熟生態、支援 Code First/Database First | 學習曲線較陡、效能調校較複雜 | 現代新專案首選 |
public interface IUserRepository
{
User GetById(int id);
void Add(User user);
void Update(User user);
void Delete(int id);
}
public class LinqUserRepository : IUserRepository
{
private readonly DataContext _ctx;
public LinqUserRepository(string connStr) { _ctx = new DataContext(connStr); }
public User GetById(int id) => _ctx.GetTable<User>().SingleOrDefault(u => u.Id == id);
public void Add(User user) { _ctx.GetTable<User>().InsertOnSubmit(user); _ctx.SubmitChanges(); }
public void Update(User user) { _ctx.SubmitChanges(); }
public void Delete(int id) { var u = GetById(id); if(u!=null) { _ctx.GetTable<User>().DeleteOnSubmit(u); _ctx.SubmitChanges(); } }
}
TransactionScope 管理跨多個 Repository 的事務。LINQ to SQL 配合自訂存儲程序,兼顧開發效率與資料庫端邏輯控制。採用 Repository Pattern 封裝 DAL,搭配 BLL 統一事務管理,構建清晰、可測試、可維護的企業級分層架構。