首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
您现在的位置: 程式碼之家 >> 編程語言 >  >> .NET 網頁程式設計 >> 關於.NET

LINQ to SQL 進階存儲程序技巧:回傳值與多結果集處理

     編輯:關於.NET

承接上篇《LINQ to SQL 存儲程序基礎映射》,本文探討兩個實務常見進階場景:擷取存儲程序整數回傳值 以及 處理多結果集。

場景一:取得存儲程序 RETURN 值

SQL Server 存儲程序可用 RETURN @intValue 回傳狀態碼 (0=成功, -1=失敗等)。但 LINQ to SQL 設計器產生的方法預設僅回傳 ISingleResult<T>,**不直接暴露 RETURN 值**。

存儲程序範例

CREATE PROCEDURE dbo.linqDemo4
    @input VARCHAR(20)
AS
BEGIN
    SELECT * FROM Customers;
    RETURN 20; -- 回傳狀態碼
END

設計器產生代碼 (無法取得 RETURN 值)

[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));
}

解決方案:包裝方法擷取 ReturnValue


public ISingleResult<Customer> linqDemo4WithReturnValue(
    string input, out int returnValue)
{
    ISingleResult<Customer> result = linqDemo4(input);
    returnValue = (int)result.ReturnValue; // 關鍵:IExecuteResult.ReturnValue 即為 SP RETURN 值
    return result;
}

呼叫端:


int spReturnCode;
var customers = ctx.linqDemo4WithReturnValue("test", out spReturnCode);
Console.WriteLine($"SP 回傳碼: {spReturnCode}"); // 輸出 20
💡 未來設計器版本或可自動識別並產生 out int returnValue 參數。

場景二:單一存儲程序回傳多個結果集

若存儲程序包含多條 SELECT,預設設計器僅映射第一個結果集,且產生匿名結果類別 (linqDemo5Result)。

存儲程序範例

CREATE PROCEDURE dbo.linqDemo5
AS
BEGIN
    SELECT * FROM Customers; -- 結果集 1
    SELECT * FROM Orders;    -- 結果集 2
END

設計器預設產生代碼

[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))]  // 聲明第 1 個結果集型別
[ResultType(typeof(Order))]     // 聲明第 2 個結果集型別
public IMultipleResults linqDemo5()
{
    return (IMultipleResults)(this.ExecuteMethodCall(this,
        ((MethodInfo)(MethodInfo.GetCurrentMethod())))).ReturnValue;
}

呼叫端依序取得結果集


var ctx = new NorthwindDataContext();
IMultipleResults results = ctx.linqDemo5();

// ⚠️ 順序必須與 SP 中 SELECT 順序一致
foreach (var c in results.GetResult<Customer>())
    Console.WriteLine($"Customer: {c.CustomerID}");

foreach (var o in results.GetResult<Order>())
    Console.WriteLine($"Order: {o.OrderID}");

關鍵限制與避坑指南

  • 順序強綁定:GetResult<T>() 呼叫順序必須與存儲程序 SELECT 順序完全一致,否則會因欄位對應失敗拋出例外。
  • 欄位名稱需精確匹配:內部使用 DataReader 依欄位名稱映射屬性,SELECT * 若資料表結構變更極易出錯,建議明確列出欄位。
  • 不支援巢狀/動態結果集:邏輯分支導致結果集數量/型別不固定時,無法靜態映射。
  • 效能考量:多結果集單次往返可減少網路延遲,但若結果集極大,記憶體壓力會瞬間飆升,需權衡。

總結

掌握 IExecuteResult.ReturnValue 擷取回傳碼、[ResultType] + IMultipleResults 處理多結果集,能讓 LINQ to SQL 在存儲程序整合上應對更複雜的實務需求。但請謹記:多結果集映射脆弱且限制多,**能拆分為多個存儲程序或改用 Table-Valued Parameters / JSON 輸出時,優先考慮替代方案**。

  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved