在我们编写程序中,往往需要一些存储过程,在LINQ to SQL中怎么使用呢?也许比原来的更简单些。下面我们以NORTHWND.MDF数据库中自带的几个存储过程来理解一下。

1.标量返回

在数据库中,有名为Customers Count By Region的存储过程。该存储过程返回顾客所在"WA"区域的数量。

ALTER PROCEDURE [dbo].[NonRowset]
(@param1 NVARCHAR(15))
AS
BEGIN
SET NOCOUNT ON;
DECLARE @count int
SELECT @count = COUNT(*)FROM Customers
WHERECustomers.Region = @Param1
RETURN @count
END

我们只要把这个存储过程拖到O/R设计器内,它自动生成了以下代码段:

[Function(Name = "dbo.[Customers Count By Region]")]
public int Customers_Count_By_Region([Parameter
(DbType = "NVarChar(15)")] string param1)
{
IExecuteResult result = this.ExecuteMethodCall(this,
((MethodInfo)(MethodInfo.GetCurrentMethod())), param1);
return ((int)(result.ReturnValue));
}

我们需要时,直接调用就可以了,例如:

int count = db.CustomersCountByRegion("WA");
Console.WriteLine(count);

语句描述:这个实例使用存储过程返回在“WA”地区的客户数。

2.单一结果集

从数据库中返回行集合,并包含用于筛选结果的输入参数。 当我们执行返回行集合的存储过程时,会用到结果类,它存储从存储过程中返回的结果。

下面的示例表示一个存储过程,该存储过程返回客户行并使用输入参数来仅返回将“London”列为客户城市的那些行的固定几列。

ALTER PROCEDURE [dbo].[Customers By City]
-- Add the parameters for the stored procedure here
(@param1 NVARCHAR(20))
AS
BEGIN
-- SET NOCOUNT ON added to prevent extra result sets from
-- interfering with SELECT statements.
SET NOCOUNT ON;
SELECT CustomerID, ContactName, CompanyName, City from
Customers as c where c.City=@param1
END

拖到O/R设计器内,它自动生成了以下代码段:

[Function(Name="dbo.[Customers By City]")]
public ISingleResult<Customers_By_CityResult> Customers_By_City(
[Parameter(DbType="NVarChar(20)")] string param1)
{
IExecuteResult result = this.ExecuteMethodCall(this, (
(MethodInfo)(MethodInfo.GetCurrentMethod())), param1);
return ((ISingleResult<Customers_By_CityResult>)
(result.ReturnValue));
}

我们用下面的代码调用:

ISingleResult<Customers_By_CityResult> result =
db.Customers_By_City("London");
foreach (Customers_By_CityResult cust in result)
{
Console.WriteLine("CustID={0}; City={1}", cust.CustomerID,
cust.City);
}

语句描述:这个实例使用存储过程返回在伦敦的客户的 CustomerID和City。

3.多个可能形状的单一结果集

当存储过程可以返回多个结果形状时,返回类型无法强类型化为单个投影形状。尽管 LINQ to SQL 可以生成所有可能的投影类型,但它无法获知将以何种顺序返回它们。 ResultTypeAttribute 属性适用于返回多个结果类型的存储过程,用以指定该过程可以返回的类型的集合。

在下面的 SQL 代码示例中,结果形状取决于输入(param1 = 1或param1 = 2)。我们不知道先返回哪个投影。

ALTER PROCEDURE [dbo].[SingleRowset_MultiShape]
-- Add the parameters for the stored procedure here
(@param1 int )
AS
BEGIN
-- SET NOCOUNT ON added to prevent extra result sets from
-- interfering with SELECT statements.
SET NOCOUNT ON;
if(@param1 = 1)
SELECT * from Customers as c where c.Region = 'WA'
else if (@param1 = 2)
SELECT CustomerID, ContactName, CompanyName from
Customers as c where c.Region = 'WA'
END

拖到O/R设计器内,它自动生成了以下代码段:

[Function(Name="dbo.[Whole Or Partial Customers Set]")]
public ISingleResult<Whole_Or_Partial_Customers_SetResult>
Whole_Or_Partial_Customers_Set([Parameter(DbType="Int")]
System.Nullable<int> param1)
{
IExecuteResult result = this.ExecuteMethodCall(this,
((MethodInfo)(MethodInfo.GetCurrentMethod())), param1);
return ((ISingleResult<Whole_Or_Partial_Customers_SetResult>)
(result.ReturnValue));
}

但是,VS2008会把多结果集存储过程识别为单结果集的存储过程,默认生成的代码我们要手动修改一下,要求返回多个结果集,像这样:

[Function(Name="dbo.[Whole Or Partial Customers Set]")]
[ResultType(typeof(WholeCustomersSetResult))]
[ResultType(typeof(PartialCustomersSetResult))]
public IMultipleResults Whole_Or_Partial_Customers_Set([Parameter
(DbType="Int")] System.Nullable<int> param1)
{
IExecuteResult result = this.ExecuteMethodCall(this,
((MethodInfo)(MethodInfo.GetCurrentMethod())), param1);
return ((IMultipleResults)(result.ReturnValue));
}

我们分别定义了两个分部类,用于指定返回的类型。WholeCustomersSetResult类 如下:

PartialCustomersSetResult类 如下:

这样就可以使用了,下面代码直接调用,分别返回各自的结果集合。

//返回全部Customer结果集
IMultipleResults result = db.Whole_Or_Partial_Customers_Set();
IEnumerable<WholeCustomersSetResult> shape1 =
result.GetResult<WholeCustomersSetResult>();
foreach (WholeCustomersSetResult compName in shape1)
{
Console.WriteLine(compName.CompanyName);
}
//返回部分Customer结果集
result = db.Whole_Or_Partial_Customers_Set();
IEnumerable<PartialCustomersSetResult> shape2 =
result.GetResult<PartialCustomersSetResult>();
foreach (PartialCustomersSetResult con in shape2)
{
Console.WriteLine(con.ContactName);
}

语句描述:这个实例使用存储过程返回“WA”地区中的一组客户。返回的结果集形状取决于传入的参数。如果参数等于 1,则返回所有客户属性。如果参数等于2,则返回ContactName属性。

4.多个结果集

这种存储过程可以生成多个结果形状,但我们已经知道结果的返回顺序。

下面是一个按顺序返回多个结果集的存储过程Get Customer And Orders。 返回顾客ID为"SEVES"的顾客和他们所有的订单。

ALTER PROCEDURE [dbo].[Get Customer And Orders]
(@CustomerID nchar(5))
-- Add the parameters for the stored procedure here
AS
BEGIN
-- SET NOCOUNT ON added to prevent extra result sets from
-- interfering with SELECT statements.
SET NOCOUNT ON;
SELECT * FROM Customers AS c WHERE c.CustomerID = @CustomerID
SELECT * FROM Orders AS o WHERE o.CustomerID = @CustomerID
END

拖到设计器代码如下:

[Function(Name="dbo.[Get Customer And Orders]")]
public ISingleResult<Get_Customer_And_OrdersResult>
Get_Customer_And_Orders([Parameter(Name="CustomerID",
DbType="NChar(5)")] string customerID)
{
IExecuteResult result = this.ExecuteMethodCall(this,
((MethodInfo)(MethodInfo.GetCurrentMethod())), customerID);
return ((ISingleResult<Get_Customer_And_OrdersResult>)
(result.ReturnValue));
}

同样,我们要修改自动生成的代码:

[Function(Name="dbo.[Get Customer And Orders]")]
[ResultType(typeof(CustomerResultSet))]
[ResultType(typeof(OrdersResultSet))]
public IMultipleResults Get_Customer_And_Orders
([Parameter(Name="CustomerID",DbType="NChar(5)")]
string customerID)
{
IExecuteResult result = this.ExecuteMethodCall(this,
((MethodInfo)(MethodInfo.GetCurrentMethod())), customerID);
return ((IMultipleResults)(result.ReturnValue));
}

同样,自己手写类,让其存储过程返回各自的结果集。

CustomerResultSet类

OrdersResultSet类

这时,只要调用就可以了。

IMultipleResults result = db.Get_Customer_And_Orders("SEVES");
//返回Customer结果集
IEnumerable<CustomerResultSet> customer =
result.GetResult<CustomerResultSet>();
//返回Orders结果集
IEnumerable<OrdersResultSet> orders =
result.GetResult<OrdersResultSet>();
//在这里,我们读取CustomerResultSet中的数据
foreach (CustomerResultSet cust in customer)
{
Console.WriteLine(cust.CustomerID);
}

语句描述:这个实例使用存储过程返回客户“SEVES”及其所有订单。

5.带输出参数

LINQ to SQL 将输出参数映射到引用参数,并且对于值类型,它将参数声明为可以为 null。

下面的示例带有单个输入参数(客户 ID)并返回一个输出参数(该客户的总销售额)。

ALTER PROCEDURE [dbo].[CustOrderTotal]
@CustomerID nchar(5),
@TotalSales money OUTPUT
AS
SELECT @TotalSales = SUM(OD.UNITPRICE*(1-OD.DISCOUNT) * OD.QUANTITY)
FROM ORDERS O, "ORDER DETAILS" OD
where O.CUSTOMERID = @CustomerID AND O.ORDERID = OD.ORDERID

其生成代码如下:

[Function(Name="dbo.CustOrderTotal")]
public int CustOrderTotal(
[Parameter(Name="CustomerID", DbType="NChar(5)")]string customerID,
[Parameter(Name="TotalSales", DbType="Money")]
ref System.Nullable<decimal> totalSales)
{
IExecuteResult result = this.ExecuteMethodCall(this,
((MethodInfo)(MethodInfo.GetCurrentMethod())),
customerID, totalSales);
totalSales = ((System.Nullable<decimal>)
(result.GetParameterValue()));
return ((int)(result.ReturnValue));
}

我们使用下面的语句调用此存储过程:注意:输出参数是按引用传递的,以支持参数为“in/out”的方案。在这种情况下,参数仅为“out”。

decimal? totalSales = ;
string customerID = "ALFKI";
db.CustOrderTotal(customerID, ref totalSales);
Console.WriteLine("Total Sales for Customer '{0}' = {1:C}",
customerID, totalSales);

语句描述:这个实例使用返回 Out 参数的存储过程。

好了,就说到这里了,其增删改操作同理。相信大家通过这5个实例理解了存储过程。

文章很好,看看都想转载,于是转了!感谢您的耐心阅读。

LINQ to SQL语句(20)之存储过程的更多相关文章

  1. 年终巨献 史上最全 ——LINQ to SQL语句

    LINQ to SQL语句(1)之Where 适用场景:实现过滤,查询等功能. 说明:与SQL命令中的Where作用相似,都是起到范围限定也就是过滤作用的,而判断条件就是它后面所接的子句.Where操 ...

  2. LINQ to SQL语句非常详细(原文来自于网络)

    LINQ to SQL语句(1)之Where Where操作 适用场景:实现过滤,查询等功能. 说明:与SQL命令中的Where作用相似,都是起到范围限定也就是过滤作用的,而判断条件就是它后面所接的子 ...

  3. LINQ to SQL语句

    http://kb.cnblogs.com/page/42477/2/ 本系列文章导航 LINQ to SQL语句(1)之Where LINQ to SQL语句(2)之Select/Distinct ...

  4. LINQ to SQL语句对应SQL的实现

    LINQ to SQL语句(1)之Where LINQ to SQL语句(2)之Select/Distinct LINQ to SQL语句(3)之Count/Sum/Min/Max/Avg LINQ ...

  5. LINQ to SQL语句大全

    LINQ to SQL语句大全     LINQ to SQL语句(1)之Where 适用场景:实现过滤,查询等功能. 说明:与SQL命令中的Where作用相似,都是起到范围限定也就是过滤作用的,而判 ...

  6. 【转】LINQ to SQL语句(1)之Where

    Where操作 适用场景:实现过滤,查询等功能. 说明:与SQL命令中的Where作用相似,都是起到范围限定也就是过滤作用的,而判断条件就是它后面所接的子句. Where操作包括3种形式,分别为简单形 ...

  7. 史上最全 ——LINQ to SQL语句

    LINQ to SQL语句(1)之Where 适用场景:实现过滤,查询等功能. 说明:与SQL命令中的Where作用相似,都是起到范围限定也就是过滤作用的,而判断条件就是它后面所接的子句.Where操 ...

  8. LINQ简介和LINQ to SQL语句之Where

    LINQ是Language Integrated Query的简称,它是集成在.NET编程语言中的一种特性.已成为编程语言的一个组成部分,在编写程序时可以得到很好的编译时语法检查,丰富的元数据,智能感 ...

  9. LINQ to SQL语句(7)之Exists/In/Any/All/Contains

    适用场景:用于判断集合中元素,进一步缩小范围. Any 说明:用于判断集合中是否有元素满足某一条件:不延迟.(若条件为空,则集合只要不为空就返回True,否则为False).有2种形式,分别为简单形式 ...

随机推荐

  1. Android性能优化之巧用软引用与弱引用优化内存使用

    前言: 从事Android开发的同学都知道移动设备的内存使用是非常敏感的话题,今天我们来看下如何使用软引用与弱引用来优化内存使用.下面来理解几个概念. 1.StrongReference(强引用) 强 ...

  2. Java虚拟机 JVM

    finalize();(不建议使用,代价高,不确定性大) 如果你在一个类中覆写了finalize()方法, 那么你可以在第一次被GC的时候,挽救一个你想挽救的对象,让其不被回收,但只能挽救一次. GC ...

  3. windows系统路径环境变量

    当前系统盘符%systemdrive%或%HOMEDRIVE%C:\ 当前系统目录%systemroot%或%Windir%C:\WINDOWS 当前用户文件夹%UserProfile%或%HOMEP ...

  4. 《CPU的工作过程》

    本文转载自inter官方网址:https://software.intel.com/zh-cn/articles/book-Processor-Architecture_CPU_work_proces ...

  5. 解除win7网络限速.

    在电脑刚买或者系统重装了的时候,win7系统会默认限制20%的网络速度,限制了我们的上网速度,我们可以解决这个限制,让上网变得更快 下面是操作步骤 1.开始>运行 2.输入以下命令,然后确定 g ...

  6. MonoDevelop 4.2.2/Mono 3.4.0 in CentOS 6.5 安装笔记

    MonoDevelop 4.2.2/Mono 3.4.0 in CentOS 6.5 安装笔记 说明 以root账户登录Linux操作系统,注意:本文中的所有命令行前面的 #> 表示命令行提示符 ...

  7. opengl 笔记(1)

    参考<opengl入门教程>.<OpenGL之坐标转换>.<OpenGL绘制管线操作细节>等资料. 复习下留个备忘:) /*- * Opengl Demo Test ...

  8. keepalived 知识备注

    keepalived可用于配置nginx/lvs等负载均衡设备的双机热备. keepalived基于VRRP协议,简单的说就是两个物理路由节点(一主一备),虚拟成一个逻辑上的路由节点. 实际消息的路由 ...

  9. Nova PhoneGap框架 第一章 前言

    Nova PhoneGap Framework诞生于2012年11月,从第一个版本的发布到现在,这个框架经历了多个项目的考验.一直以来我们也持续更新这个框架,使其不断完善.到现在,这个框架已比较稳定了 ...

  10. [异常解决] JLINK 与STM32的SWD连接接线方式

    如果我们的板子上只留了4个接口:V3.3,SWDIO,SWDCLK,GND.那么和JTAG的连接关系参见下图: 注意缺口方向.然后GND可以接左边任何一个pin(除了最底下这个PIN). FROM: ...