c#与返回多表的存储过程

存储过程返回值的代码:

方法一:output

Create PROCEDURE [dbo].[P_GetSomething]
@id varchar(20),
@info int output

方法二:select

Create PROCEDURE [dbo].[P_GetSomething]
@id varchar(20)AS
set nocount on

select * from dbo.[Table1]
select * from dbo.[Table2]
select * from dbo.[Table3]

方法三:return

Create PROCEDURE [dbo].[P_GetSomething]
@id varchar(20)AS
set nocount on

return 0

 在linq to sql的dbml文件中,拖进相应的存储过程,在design.cs中会自动生成调用方法。其中,output的返回值会用ref的参数来承载,而return的值直接反映在方法的返回类型中。select的返回类型是一个表,在c#端会自动生成一个P_GetSomething的类型,类型的结构与返回表的有相同的字段属性。但是,如果存储过程返回的是多个表会怎么样呢?多个表的情况,c#端只会自动生成第一个表的返回代码。

return的代码:

[global::System.Data.Linq.Mapping.FunctionAttribute(Name="dbo.P_GetSomething")]
public int P_GetSomething([global::System.Data.Linq.Mapping.ParameterAttribute(DbType="VarChar(20)")] string id)
{
    IExecuteResult result = this.ExecuteMethodCall(this, ((MethodInfo)(MethodInfo.GetCurrentMethod())), id);
    return ((int)(result.ReturnValue));
}

output+select的代码:

[global::System.Data.Linq.Mapping.FunctionAttribute(Name="dbo.P_GetSomething")]
public ISingleResult<P_GetSomething> P_GetSomething([global::System.Data.Linq.Mapping.ParameterAttribute(DbType="VarChar(20)")] string id, [global::System.Data.Linq.Mapping.ParameterAttribute(DbType="Int")] ref System.Nullable<int> info)
{
    IExecuteResult result = this.ExecuteMethodCall(this, ((MethodInfo)(MethodInfo.GetCurrentMethod())), id, info);
    info = ((System.Nullable<int>)(result.GetParameterValue(1)));
    return ((ISingleResult<P_GetSomething>)(result.ReturnValue));
}

多个select的情况:

[global::System.Data.Linq.Mapping.FunctionAttribute(Name="dbo.P_GetSomething")]
public ISingleResult<P_GetSomething> P_GetSomething([global::System.Data.Linq.Mapping.ParameterAttribute(DbType="VarChar(20)")] string id)
{
    IExecuteResult result = this.ExecuteMethodCall(this, ((MethodInfo)(MethodInfo.GetCurrentMethod())), id);
    return ((ISingleResult<P_GetSomething>)(result.ReturnValue));
}

如果想将多个select的表全部返回,修改代码如下:

[global::System.Data.Linq.Mapping.FunctionAttribute(Name = "dbo.P_GetSomething")]
[ResultType(typeof(TableA))]
[ResultType(typeof(TableB))]
[ResultType(typeof(TableC))]public IMultipleResults P_GetSomething([global::System.Data.Linq.Mapping.ParameterAttribute(DbType = "VarChar(20)")] string id)
{
    IExecuteResult result = this.ExecuteMethodCall(this, ((MethodInfo)(MethodInfo.GetCurrentMethod())), id);
    return ((IMultipleResults)(result.ReturnValue));
}

在数据获取的执行端,调用赋值时,一定要按照顺序,不能先取TableC,再取TableA

var result = db.P_GetSomething(id);
var a = result.GetResult<TableA>().ToList();
var b = result.GetResult<TableB>().ToList();
var c = result.GetResult<TableC>().ToList();

另外还要注意,Linq是延迟查询语句,所以在这里取值时,全部用ToList阻止了延迟。这样做的原因是因为,如果出现了延迟查询,或者多次查询,数据的输出顺序一直都是先A后B最后C,我们赋值时,可能用TableC xx = result.GetResult<TableC>(); 这时result输出的数据可能是TableA,就会引起类型不对的错误。有点类似队列,先进先出的原则,有一定的取值顺序。

 

posted @ 2013-05-22 10:41  脸谱匠  阅读(2755)  评论(0编辑  收藏  举报