本文接著上篇文章Linq to SQL之使用存儲過程 (1),繼續探討如何在Linq to SQL中使用存儲過程。
在寫存儲過程的時候,有時候會用到返回值而不是output參數,現在看看怎樣取到該返回值呢?
比如這樣一個存儲過程:
create procedure dbo.linqDemo4
@input varchar(20)
as
select * from customers
return 20
設計器自動生成的函數如下,可以看到並沒有提供方式取到該存儲過程的返回值:
[Function(Name="dbo.linqDemo4")]
public ISingleResult<Customer> linqDemo4([Parameter(DbType="VarChar(20)")] string input) {
IExecuteResult result = this.ExecuteMethodCall(this, ((MethodInfo) (MethodInfo.GetCurrentMethod())), input);
return ((ISingleResult<Customer>)(result.ReturnValue));
}
只能靠自己了,增加一個函數對它進行包裝,以此來取到返回值
public ISingleResult<Customer> linqDemo4WithReturnValue(string input, out int returnValue)
{
ISingleResult<Customer> result = linqDemo4(input);
returnValue = (int)result.ReturnValue;
return (ISingleResult<Customer>)(result);
}
增加一個out參數returnValue,這樣就能從結果中取到這個返回值。不知道以後的設計器能不能自動 識別。
有時候會到這種需求,存儲過程返回多個結果集合,那麼這時候怎麼操作才能把結果集分開呢。比如 下面這個存儲過程,能不能把Customer和Order的結果集分別取到呢?
create procedure dbo.linqDemo5
as
select * from customers
select * from orders
linqDemo5Result裡面只包括customer表的所有字段。不過,Linq to SQL中提供了ResultType Attribute來標志該存儲過程會返回什麼類型的對象以及IMultipleResults接口來滿足獲得多個結果集的 問題。首先看看自動生成的方法:
[Function(Name="dbo.linqDemo5")]
public ISingleResult<linqDemo5Result> linqDemo5()
{
IExecuteResult result = this.ExecuteMethodCall(this, ((MethodInfo) (MethodInfo.GetCurrentMethod())));
return ((ISingleResult<linqDemo5Result>)(result.ReturnValue));
}
我們對它進行修改,用ResultType標記返回的結果中將包含哪些類型,再使用IMultipleResults返回 多個結果集
[Function(Name="dbo.linqDemo5")]
[ResultType(typeof(Customer))]
[ResultType(typeof(Order))]
public IMultipleResults linqDemo5() {
return (IMultipleResults)(this.ExecuteMethodCall(this,
((MethodInfo)(MethodInfo.GetCurrentMethod())))).ReturnValue;
}
在我們的代碼中如下使用:
NorthwindDataContext ctx = new NorthwindDataContext();
IMultipleResults results = ctx.linqDemo5();
foreach (var c in results.GetResult<Customer>())
{
Console.WriteLine(c);
}
foreach (var o in results.GetResult<Order>())
{
Console.WriteLine(o);
}
值得注意的是GetResult的順序依賴於存儲過程中返回結果的順序,如果先返回customer結果集就必須 先調用GetResult<Customer>,否則會出現異常。可以說在調用GetResult的時候,根據對象屬性映 射列來取值,一旦發現不匹配就會出現錯誤。假設裡面使用的dataReader,構造Customer對象的時候對屬 性進行賦值,c.CustomerID=reader["CustomerID"],如果沒有這一列就拋出異常了。所以說在存儲過程 中使用多個結果集限制性非常大。