本文接着上篇文章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"],如果没有这一列就抛出异常了。所以说在存储过程中使用多个结果集限制性非常大。

 posted on 2007-07-11 16:23  紫色阴影  阅读(4306)  评论(8编辑  收藏  举报
我要啦免费统计