2011-07-22 63 views
16

我在一些項目中使用了實體框架。在每個項目中,我都使用映射到實體的存儲過程,這是因爲存儲過程的衆所周知的好處 - 安全性,可維護性等。但是,99%的存儲過程是基本的CRUD存儲過程。這看起來像是否定了實體框架 - SQL生成的主要節省時間的功能之一。實體框架存儲過程與生成的SQL

我讀過一些有關存儲過程與實體框架中生成的SQL的爭論。雖然使用CRUD SPs對於安全性更好,而EF生成的SQL通常比必要的更復雜,但它是否真正購買了使用SP的性能或可維護性方面的任何內容?

這裏是什麼,我相信:

  • 大部分的時間,修改SP需要更新數據模型 反正。所以,在可維護性方面並沒有太多的購買。
  • 對於Web應用程序,與數據庫的連接使用特定於應用程序的單個用戶ID。因此,用戶甚至沒有直接的數據庫訪問權限。這降低了安全效益。
  • 對於一個小型應用程序,使用生成的SQL稍微降低的性能可能不是什麼大問題。對於音量高,性能關鍵的應用程序,EF甚至會明智地選擇 ?另外,EF生成的插入/更新/刪除語句 真的很糟糕嗎?
  • 將每個屬性發送到存儲過程都有其自身的性能損失,而EF生成的代碼只發送實際更改的屬性。在對大型表進行更新時,增加的網絡流量和更新所有屬性的開銷可能會否定存儲過程的性能優勢。

雖這麼說,我的具體問題是:

上面列出的正確我的信念?現在ORM越來越受歡迎,總是使用SP的東西是「老派」的想法嗎?根據你的經驗,對於所有插入/更新/刪除操作使用EF映射SP,或將EF生成的SQL用於CRUD操作並僅將SP用於更復雜的東西,哪種方法更好?

+0

'修改SP需要更新數據模型anyway' SP結束了顯著提高應用程序的維護成本,不只是因爲你不得不在至少5處(每一個變化每1 SP插入,更新,和刪除,至少有一個用於選擇,然後也用於實體模型),但也因爲對於任何不是簡單的CRUD操作的應用程序而言,您都將應用程序邏輯隱藏在應用程序之外,開發人員必須在不同的應用程序之間來回跳動IDE的。 –

回答

33

我認爲總是使用SP的是有點老派。我曾經以這種方式進行編碼,並且現在盡我所能在EF生成的代碼中進行編碼......當我遇到性能問題或其他特殊需求時,我會將其添加回戰略SP中以解決特定問題....它不一定是或兩者兼而有之。

我所有的基本CRUD操作都是直接生成EF代碼 - 我的網絡應用程序曾經有100多個或更多的SP,現在一般會有一打SP,其他所有事情都在我的C#代碼中完成......並且我的生產力已經消除了95%的CRUD存儲過程。

+0

+1一個好的,務實的方法 - 我可能也會這樣。儘可能多地使用EF,但是如果知道**如果需要在某個地方的INSERT語句中調整性能的最後一滴性能,您可以使用存儲過程來處理它。 –

+0

正如你所說因爲性能問題,寫一個SP真的很值得,但如何使用視圖(當然不是SP中的select查詢)呢?我找不到任何與這兩種方法之間的比較有關的事情。 –

6

如果性能是您最關心的問題,那麼您應該選擇一個現有的使用EF的應用程序,禁用SP並對新版本進行基準測試。這是獲得完全適用於您的情況的答案的唯一方法。您可能會發現,無論您做什麼與自定義代碼相比,您的性能需求都不夠快,但在超大容量網站之外,我認爲EF 4.1實際上是非常合理的。

從我的PoV來看,EF提高了開發人員的生產力。如果你正在爲簡單的CRUD操作編寫SP,並且特別是插入/更新/刪除,我真的沒有看到你獲得了很多性能,因爲這些操作對於生成SQL來說非常簡單。肯定有一些選擇情況下,EF不會做最佳的事情,你可以通過編寫一個SP來獲得主要的性能提升(在Oracle中使用CONNECT BY進行分層查詢的例子)。

處理這種類型的東西,最好的辦法是寫你的應用程序出租EF生成SQL。基準。找到存在性能問題的地方,併爲這些地區編寫SP。刪除幾乎不會是您需要執行此操作的情況之一。

正如你所說,這裏的安全增益,多少削弱,因爲你應該有反正都有自己的帳戶爲應用程序的應用程序層EF,所以你可以限制它做什麼。 SP確實給了你更多的控制權,但在典型的使用情況下,我認爲它不重要。

它不具有忠實地正確或錯誤的答案一個有趣的問題。我主要使用EF,因此我不必寫通用的CRUD SP,而是可以將時間花在處理更復雜的案例上,所以對於我來說,我應該說你應該寫出更少的案例。 :)

12

是你的信念是完全正確的。使用存儲過程進行數據操作具有意義,主要如:

  • 數據庫如下,其中變化的數據通過存儲過程只允許
  • 您正在使用的視圖或自定義查詢映射你的實體嚴格的安全規則,你需要先進的邏輯在存儲過程,以將數據傳輸回
  • 你有一些先進的邏輯程序(相關數據)任何其他原因

使用過程純CUD其中提到的情況下,不適用是多餘的,它不提供任何可測量的性能提升,除了單一的方案

  • 您將使用存儲過程批量/批量修改

EF沒有因此更改1000個記錄導致1000個更新散裝/批處理功能每個執行單獨的數據庫往返!但是這樣的過程無論如何都不能映射到實體,並且必須通過函數導入(如果可能的話)或者直接以ExecuteStoreCommand或舊的ADO.NET(例如,如果您想使用表值參數)單獨執行。

的完全不同的故事可以是R在CRUD其中存儲過程可以得到顯著的性能提升與自己優化的查詢讀取數據。

1

我E.J廣泛認同,但也有一些其他的選擇。這真的歸結爲特定系統的要求:

  • 您是否需要開發應用程序FAST? - 然後使用實體框架及其自動SQL
  • 需要細粒度和可靠的安全性? - 進入存儲過程
  • 需要運行儘可能快嗎? - 你可能正在看一些快樂的媒介!
0

在我看來,只要您的應用程序/數據庫不會遇到性能問題,並且您主要使用CRUD數據庫並使用一個數據庫用戶訪問數據庫,則最好使用生成的SQL。開發速度更快,更易維護,少數安全或更多隱私優勢不值得(如果數據不那麼敏感)。此外,使用基於模型的數據庫訪問或LINQ禁用了SQL注入的威脅。