[譯]DbContext API中使用SqlQuery和ExecuteSqlCommand獲取存儲過程的輸入輸出參數


水平有限,歡迎指正。
原文:http://blogs.msdn.com/b/diego/archive/2012/01/10/how-to-execute-stored-procedures-sqlquery-in-the-dbcontext-api.aspx

 Entity Framework 4.1中引入的DbContext API暴露了一些新的方法用於提供透傳原生SQL給數據庫執行查詢和命令,比如 Database.SqlQuery<T>, 以及 Database.ExecuteSqlCommand。

這些方法很重要不僅僅因為它們允許你執行自己的原生SQL查詢,而且因為它們是當前你可以使用DbContext訪問存儲過程的主要方法,特別當你使用代碼優先的開發模式。

就實現而言,它們是在EF 4.0中加入的ObjectContext.ExecuteStoreQuery<T> 和 ObjectContext.ExecuteStoreCommand 的更簡單變種。不管怎么說,關於這些方法可以做什么看上去還是會有一些困惑,尤其是它們支持的查詢語法。

簡而言之我覺得以下幾點可以說明這些方法是怎么工作的:
1、傳遞給方法的查詢文本會被設置給來自底層ADO.NET提供程序的DbCommand對象。
2、DbCommand對象是通過設置CommandType屬性值為CommandType.Text來執行的。
3、此外,如果方法會返回你之前傳遞的對象類型的結果(例如SqlQuery<T>),這個結果是基於DbDataReader返回的值所提取的。

你可以使用類似下面的語法,從一個存儲過程返回的必要列中提取一個個人實體對象:

1 var idParam = new SqlParameter { 
2      ParameterName = "id",  
3      Value = 1}; 
4 var person = context.Database.SqlQuery<Person>( 
5      "GetPerson @id",  
6      idParam);

為了方便這些方法同時也接收普通的原始類型參數。你可以使用類似“{0}”的語法在查詢語句中使用這些參數。

var person = context.Database.SqlQuery<Person>(
     "SELECT * FROM dbo.People WHERE Id = {0}", id);

可是這些語法適用性有局限,而且可能你要做的一些事情需要更好的控制,像調用一個帶輸入輸出參數的存儲過程,或者參數不是基本類型,你必須使用數據源所支持的完整的SQL語法。

我想分享一個關於使用輸入輸出參數的簡單例子,這樣可以更好的舉例說明。

在你的SQL Server數據庫中創建一個(完整但沒什么用)存儲過程定義:

 1 CREATE PROCEDURE [dbo].[GetPersonAndVoteCount] 
 2  ( 
 3    @id int, 
 4    @voteCount int OUTPUT 
 5  ) 
 6  AS 
 7  BEGIN 
 8    SELECT @voteCount = COUNT(*) 
 9    FROM dbo.Votes 
10    WHERE PersonId = @id; 
11    SELECT * 
12    FROM dbo.People 
13    WHERE Id = @id; 
14  END

你可以寫一段如下所示的代碼執行它:

 1 var idParam = new SqlParameter {
 2       ParameterName = "id",
 3       Value = 1};
 4  var votesParam = new SqlParameter {
 5       ParameterName = "voteCount",
 6       Value = 0,
 7       Direction = ParameterDirection.Output };
 8  var results = context.Database.SqlQuery<Person>(
 9      "GetPersonAndVoteCount @id, @voteCount out",
10       idParam,
11       votesParam);
12  var person = results.Single();
13  var votes = (int)votesParam.Value;

在上面這段代碼中有幾個注意事項:
1、SqlQuery和ExecuteSqlCommand方法所支持的主要語法是被底層ADO.NET提供程序所支持的原生SQL語法。(有人在評論中提到SQL Server 2005必須在存儲過程名前面加上EXEC關鍵字)。
2、DbCommand是使用CommandType.Text(相對於CommandType.StoredProcedure)來執行的,這意味着它不會自動為存儲過程綁定參數,盡管如此你還是可以使用普通的SQL語法來執行存儲過程。
3、你必須使用正確的語法來為存儲過程傳遞一個輸入輸出參數,比如你需要在SQL語句中參數名稱的后面增加一個“OUT”關鍵字。
4、輸入和輸出參數僅僅在使用實際的DbParameters類型的時候起作用(在這個例子中我們使用SqlParameters因為我們使用SQL Server),SqlQuery和ExecuteSqlCommand所支持的普通類型對象是不支持輸入輸出參數的。(譯注:SqlQuery和ExecuteSqlCommand的參數要么全部是DbParameter參數,要么全部是普通類型對象)
5、在你訪問輸入輸出參數你必須讀整個返回結果(這個例子我們通過Single方法獲取),但這是存儲過程工作原理不是特定於EF的特性。

一旦你學會了,你可以使用提供程序特定參數和底層數據源的原生SQL語法,你能夠獲取更多和你使用ADO.NET相同的靈活性,但是使用ADO.NET無法獲得重用同一個EF所維護的數據庫連接的便利性和直接從查詢結果中獲取對象的能力。

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM