簡體   English   中英

實體框架和存儲過程

[英]Entity Framework & Stored Procedures

我注意到在Entity Framework設計器中,您可以映射Insert,Update和Delete操作的存儲過程。 是否有任何方法可以為Select操作執行此操作,或者是否有新的數據庫訪問代碼方向,我們不再為基本的選擇操作編寫存儲過程了?

我工作的公司非常堅持總是使用存儲過程進行每個數據庫操作,即使實體框架通過調用sp_executesql使調用安全。

LINQ to SQL和Entity Framework似乎已經不再使用存儲過程來選擇數據了。 這是一個准確的陳述嗎?

只是為了澄清我的問題:

我的數據庫中有一個名為Product的表。 我使用實體框架中的向導來生成我的模型......所以我現在有一個名為Product的實體。 當我執行以下查詢時:

db.Products.SingleOrDefault(p => p.Id == 1);

它生成的代碼類似於:

EXEC sp_executesql N'SELECT * FROM Product'

當我真的想要做的事情:

EXEC up_GetProduct @Id = 1

如果使用SingleOrDefault無法做到這一點,我就可以了。 我更願意擁有以下內容:

db.Products.GetProduct(1);

這是通常完成的事情還是大多數人只是讓它動態生成SQL?

實體本身不允許存儲過程進行選擇。 有幾個原因。 脫離我的頭頂:

  1. 如何在存儲過程中添加where子句? 您可能必須使用LINQ to Objects執行此操作並且查詢效率低下,或者以某種方式能夠將自定義映射添加到存儲過程屬性。 雖然並非不可能,但它肯定會引入一些實現復雜性
  2. 實體可以具有用於在查詢中進行連接的關系。 使用存儲過程,您又會遇到類似的問題。 如果您有OrderOrderItem表,那么您如何加入? 您可以運行SelectOrder ,也可以為每個訂單運行SelectOrderItem (1 + n個查詢),或者讓一個存儲過程同時返回兩者,或者作為一個帶有重復Order數據的結果集,或者兩個結果集。 然后,您必須指定映射到實體的方式。 如果必須手動指定映射,則會破壞您必須設置的實體關系的目的。
  3. 你怎么做分頁? 使用LINQ to Entities,您可以將IQueryable公開給業務層或UI層(由您決定)。 然后進行LINQ過濾,修改SQL並使其高效。 使用存儲過程,您將再次以某種方式手動定義所有這些,或使用LINQ to對象進行過濾。
  4. LINQ允許您select new { o.Column1, o.Column2 } 這會生成SQL,只選擇您需要的那兩列。 如果你有一個BLOB / VARCHAR(MAX)非常有用。 使用存儲過程,您通常會返回每一列(在很多方面都會浪費)。 您可以拆分為GetOrderDetailMainGetOrderDetailImages (或類似的)存儲過程,但創建每個組合是不可行的。

在我看來,如果你將使用EF框架,讓它為你做CRUD。 使用存儲過程來處理復雜的邏輯,例如全文搜索,特定查詢太慢等等。否則你將無法從中受益。

編輯 :當然存儲過程有好處。 它們是預先編譯/預編譯的,定義良好的“數據庫API”,你不需要提供對表的訪問(雖然使用SP CRUD,你實際上可以做同樣的事情),更容易調試/調優查詢,更容易知道哪些查詢可以調整,可以進行批處理等。但是,對於簡單的CRUD,您必須問自己,實現/管理存儲過程的開銷是否值得。

您當然可以在Entity Framework中使用存儲過程進行選擇。 我使用EF4在函數導入復雜類型和存儲過程方面取得了巨大成功。 而且,它們也不難設置。

我將警告您一件事:如果您使用的是SQL Server 2005,則可能必須重新編譯要使用SET FMTONLY OFF任何存儲過程,如果您希望允許實體建模器為您生成復雜類型。 有關詳細信息,請參閱此問題

有關詳細信息,請參閱快速入門

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM