Linq to Oracle 使用教程(七)将数据库的存储过程映射到方法
2010-12-04 16:47 麦舒 阅读(964) 评论(0) 编辑 收藏 举报双击 GET_CATEGORIES_AND_PRODUCTS 存储过程,代码如下:

PACKAGE BODY PKG3 IS
PROCEDURE GET_CATEGORIES_AND_PRODUCTS(MYCS1 OUT MYTYPE1, MYCS2 OUT MYTYPE2) IS
BEGIN
OPEN MYCS1 FOR SELECT CATEGORYID, CATEGORYNAME, DESCRIPTION
FROM CATEGORIES;
OPEN MYCS2 FOR SELECT PRODUCTID, PRODUCTNAME
FROM PRODUCTS;
END GET_CATEGORIES_AND_PRODUCTS;
END PKG3;
这个存储过程是使用两个返回参数返回结果的,并且这两个参数是游标类型,对于与游标类型对应的 .NET CLR 类型是 Oracle.DataAccess.Types.OracleRefCursor 。

public partial class NorthwindDataContext : ALinq.DataContext
{
[ALinq.Mapping.Function(Name = "PKG3.GET_CATEGORIES_AND_PRODUCTS")]
public void GetCategoryAndProducts(out OracleRefCursor cursor1, out OracleRefCursor cursor2)
{
cursor1 = null;
cursor2 = null;
var result = ExecuteMethodCall(this, (MethodInfo)MethodBase.GetCurrentMethod(), cursor1, cursor2);
cursor1 = (OracleRefCursor)result.GetParameterValue(0);
cursor2 = (OracleRefCursor)result.GetParameterValue(1);
}
}
映谢到该存储过程的方法如下:

public partial class NorthwindDataContext : ALinq.DataContext
{
[ALinq.Mapping.Function(Name = "PKG3.GET_CATEGORIES_AND_PRODUCTS")]
public void GetCategoryAndProducts(
[ALinq.Mapping.Parameter(Name = "MYCS1", DbType = "REF CURSOR")]
out Oracle.DataAccess.Types.OracleRefCursor cursor1,
[ALinq.Mapping.Parameter(Name = "MYCS2", DbType = "REF CURSOR")]
out Oracle.DataAccess.Types.OracleRefCursor cursor2)
{
cursor1 = null;
cursor2 = null;
var result = ExecuteMethodCall(this, (MethodInfo)MethodBase.GetCurrentMethod(), cursor1, cursor2);
cursor1 = (OracleRefCursor)result.GetParameterValue(0);
cursor2 = (OracleRefCursor)result.GetParameterValue(1);
}
}
我们很容易发现,和前面不同的是,cursor1 和 cursor2 参数前面都加了一个 out ,另外,由于该存储过程带有返回的参数,因此需要调用 result.GetParameterValue(index) 来获得该参数的返回值,其中 Index 为参数的次序。
调用代码:

static void Main(string[] args)
{
var dc = new NorthwindDataContext() { Log = Console.Out };
OracleRefCursor cursor1 = null;
OracleRefCursor cursor2 = null;
dc.Connection.Open();
dc.GetCategoryAndProducts(out cursor1, out cursor2);
var categories = dc.Translate<Category>(cursor1.GetDataReader()).ToArray();
var products = dc.Translate<Product>(cursor2.GetDataReader()).ToArray();
dc.Connection.Close();
foreach (var category in categories)
Console.WriteLine("{0} {1}", category.Categoryid, category.Categoryname);
foreach (var product in products)
Console.WriteLine("{0} {1}", product.Productid, product.Productname);
}
由于需要用到 Reader , 因此连接必须一定保持打开状态,直接数据读取完毕。因此需要显式打开连接(dc.Connection.Open),在使用完后再关闭(dc.Connection.Close)。
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 如何编写易于单元测试的代码
· 10年+ .NET Coder 心语,封装的思维:从隐藏、稳定开始理解其本质意义
· .NET Core 中如何实现缓存的预热?
· 从 HTTP 原因短语缺失研究 HTTP/2 和 HTTP/3 的设计差异
· AI与.NET技术实操系列:向量存储与相似性搜索在 .NET 中的实现
· 地球OL攻略 —— 某应届生求职总结
· 周边上新:园子的第一款马克杯温暖上架
· Open-Sora 2.0 重磅开源!
· .NET周刊【3月第1期 2025-03-02】
· [AI/GPT/综述] AI Agent的设计模式综述