
看到 EF 實際生成的命令,DBA 首先反應往往是:「什麼?我必須給表訪問權?」因為 EF 核心功能正是生成 SELECT、UPDATE、INSERT、DELETE 命令。本文將帶 DBA 了解 EF 命令生成機制,並介紹如何僅允許 EF 使用視圖與存儲過程,限制其對表的直接訪問,且不影響應用程式代碼、不傷團隊和諧。
EF 核心是實體數據模型 (EDM),描述應用領域物件的概念模型。開發者針對 EDM 查詢,無需操心資料庫細節。EDM 實體與關係以 XML 定義,開發者操作強類型類。EF 運行時利用 EDM XML 與其他元數據(描述資料庫架構及 EDM 到資料庫的映射)溝通類與資料庫(見圖 1)。

運行時,EF 利用 ADO.NET Provider 將針對 EDM 的查詢轉為存儲查詢 (如 T-SQL) 送資料庫,結果轉為強類型實體物件(見圖 2)。

物件變更時,EF 利用標識鍵追蹤屬性與關係變更。調用 SaveChanges 時,EF 讀取變更追蹤資訊,讓 Provider 生成存儲命令,在單一可逆事務中執行。這預設行為常讓 DBA 抓狂,但關鍵在於「預設」——此行為可修改。
建模方法多種,重點討論對現有資料庫反向工程建模。VS 向導可選表、視圖、存儲過程。通常開發者選表,EF 自動為基於表的實體生成 INSERT/UPDATE/DELETE。
視圖映射要點:
SaveChanges 時持久化到資料庫。為持久化變更,可覆蓋預設命令生成,映射 Insert/Update/Delete 存儲過程,稱「存儲過程映射」。
向導選入的存儲過程成為模型資料庫架構部分的函數,不自動成概念模型一部分。需在設計器「映射詳細信息」視窗映射到實體(見圖 3)。

關鍵點: PersonID 屬性映射到存儲過程返回值,執行插入後 EF 立即用資料庫生成鍵更新記憶體物件。映射要求:函數每個參數必須映射到實體某屬性,不允許公式/常值映射參數。可映射 Update/Delete 函數,不必全映射但需遵循文檔規則。屬性右側有「使用原始值」與「影響行數」欄,支援樂觀並發檢查。
運行時,用戶創建新 Person 並觸發 SaveChanges,EF 執行映射的存儲過程而非動態生成 INSERT:
exec [dbo].[InsertPerson] @FirstName=N'Julie', @LastName=N'Lerman', @Title=N'Ms.'
基於視圖的實體可能不可更新。若視圖不可更新,映射 Insert/Update/Delete 存儲過程到實體,即可完成完整數據檢索與持久化,無需授予表直接訪問權。
查詢創建優勢示例: 應用程式查詢 CustomersInPastYear 並按 LastName 篩選,EF 生成 SQL 對視圖進一步 WHERE 篩選。若用存儲過程,EF 會執行過程取所有結果再記憶體篩選,造成資源浪費與性能損耗。
圖 4 為更新 Customer 表的存儲過程,可作 CustomersInPastYear 實體的 Update 函數。圖 5 展示映射:初始 TimeStamp 送入過程,結果列綁定捕獲更新後 TimeStamp。

總結:模型設計得當、視圖實體有正確標識鍵、函數正確映射,即可不公開資料庫表給 EF 應用。視圖與存儲過程能提供 EDM 與 EF 與資料庫成功交互所需一切。