调用EF的存储过程报“存储区数据提供程序返回的数据读取器所具有的列数对于所请求的查询不够”问题
在运用Entity Framework调用存储过程的时候,遇到"调用EF的存储过程报"调用EF的存储过程报“存储区数据提供程序返回的数据读取器所具有的列数对于所请求的查询不够”问题"的问题,存储过程是用EF模型的函数导入(设置映射的存储过程)。检查过存储过程,在Sql Management Studio运用是正常的。
存储过程的部分代码如下:
ALTER PROCEDURE [dbo].[GetNameByCustomerId] -- Add the parameters for the stored procedure here @CustomersId NVARCHAR(10), @CustomerName NVARCHAR(20) OUTPUT AS BEGIN from -- interfering with SELECT statements. SET NOCOUNT ON; ……… SELECT @CustomerName=c.CompanyName FROM Customers c WHERE c.CustomerID=@CustomersId END
调用存储过程的EDMX的方法如下:
public void GetNameByCustomerId(string CustomerId, out string ContactName) { ContactName = string.Empty; var Pars = new System.Data.EntityClient.EntityParameter[] { new System.Data.EntityClient.EntityParameter{ ParameterName="CustomersId", DbType=System.Data.DbType.String,Value=CustomerId}, new System.Data.EntityClient.EntityParameter{ParameterName="CustomerName", DbType=System.Data.DbType.String, Direction=System.Data.ParameterDirection.Output} }; this.ExecuteNonQuery("GetNameByCustomerId", Pars); ContactName = Pars[1].Value.ToString(); }
函数与存储过程应该都是没有问题,在折腾了最后,发现我在函数导入(设置映射的存储过程)时候,设置了存储过程返回的集合。如图:
添加函数导入的返回类型是指最后一个SELECT语句的字段类型(仅返回一个字段的情况);所以如果没有使用SELECT语句返回则应该置返回类型为“无”;如果SELECT多个字段或者数据表行时必须将返回类型指定为“实体”(即DTO类型);如果是表就必须建一个对应的DTO;如果返回若干字段则必须为这些字段手工创建DTO类型。如果是返回DTO类型的则无需在分部类封装方法了,直接使用导入的函数即可。
解决方法:
1). 在存储过程return前,添加一条select语句,"select 1 as Result" ,使得存储过程在return时有行列返回;
2). 不使用select 结果,则不需要返回类型,将添加函数导入时指定返回类型为“无”即可