存储过程返回值的代码:
方法一: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,就会引起类型不对的错误。有点类似队列,先进先出的原则,有一定的取值顺序。