调用EF的存储过程报“存储区数据提供程序返回的数据读取器所具有的列数对于所请求的查询不够”问题
2010-08-20 11:21
549 查看
最近使用EF的函数导入(设置映射的存储过程)遇到该问题。从错误描述很难知道问题发生在哪里?一遍又一遍核对了代码的参数名称和存储过程的参数名称是否一致,也使用SQL探查器跟到执行的sql语句都正常返回结果。
存储过程简要说明如下(代码一):
Edmx中的封装方法如下(代码二):
最后发现在添加函数导入时指定了返回类型为标量Boolean,而当时我理所当然的认为该返回类型是指存储过程最后的Return语句的返回值类型(就这样设置了,因为成功Return 1,失败Return 0);下面是添加函数导入画面(图1):
当时存储过程代码(参见代码一)没有Select 1 as Result这句的,所以总是报如下错误:
后来在Return前增加了上述Select语句就OK,至此才明白添加函数导入的返回类型是指最后一个SELECT语句的字段类型(仅返回一个字段的情况);所以如果没有使用SELECT语句返回则应该置返回类型为“无”;如果SELECT多个字段或者数据表行时必须将返回类型指定为“实体”(即DTO类型);如果是表就必须建一个对应的DTO;如果返回若干字段则必须为这些字段手工创建DTO类型。如果是返回DTO类型的则无需在分部类封装方法了,直接使用导入的函数即可。
总结:如果不使用最后SELECT结果的话,则不必理会返回类型,将返回类型设置为“无”即可,当然我们封装的函数可以获取存储过程Return结果及OUTPUT类型的参数。所以上面例子代码可以删除存储过程中的Return前的Select语句,同时添加函数导入时指定返回类型为“无”。
存储过程简要说明如下(代码一):
CREATE PROCEDURE [dbo].[pmsvr_ChangeBillingMode] ( @in_iPhysicalRegisterId int, @in_bIsBillingOnline bit, @in_iModifiedEmployeeId int, @out_sErrMsg nvarchar(255) output ) AS SET NOCOUNT ON ... ... set @out_sErrMsg = '' select 1 as Result return 1 SET NOCOUNT OFF
Edmx中的封装方法如下(代码二):
public bool ChangeBillingMode(int physicalRegisterId, bool isBillingOnline, int modifiedEmployeeId, out string errMsg) { this.Connection.Open(); EntityCommand cmd = ((EntityConnection)this.Connection).CreateCommand(); cmd.CommandText = this.DefaultContainerName + ".ChangeBillingMode"; cmd.CommandType = CommandType.StoredProcedure; cmd.Parameters.AddWithValue("in_iPhysicalRegisterId", physicalRegisterId); cmd.Parameters.AddWithValue("in_bIsBillingOnline", isBillingOnline); cmd.Parameters.AddWithValue("in_iModifiedEmployeeId", modifiedEmployeeId); EntityParameter para2 = new EntityParameter("out_sErrMsg", DbType.String); para2.Direction = ParameterDirection.Output; para2.Value = string.Empty; cmd.Parameters.Add(para2); EntityParameter ret = new EntityParameter("ReturnValue", DbType.Int32); ret.Direction = ParameterDirection.ReturnValue; ret.Value = 0; cmd.Parameters.Add(ret); cmd.ExecuteNonQuery(); errMsg = cmd.Parameters["out_sErrMsg"].Value.ToString(); int returnValue = (int)cmd.Parameters["ReturnValue"].Value; return (returnValue > 0); }
最后发现在添加函数导入时指定了返回类型为标量Boolean,而当时我理所当然的认为该返回类型是指存储过程最后的Return语句的返回值类型(就这样设置了,因为成功Return 1,失败Return 0);下面是添加函数导入画面(图1):
当时存储过程代码(参见代码一)没有Select 1 as Result这句的,所以总是报如下错误:
后来在Return前增加了上述Select语句就OK,至此才明白添加函数导入的返回类型是指最后一个SELECT语句的字段类型(仅返回一个字段的情况);所以如果没有使用SELECT语句返回则应该置返回类型为“无”;如果SELECT多个字段或者数据表行时必须将返回类型指定为“实体”(即DTO类型);如果是表就必须建一个对应的DTO;如果返回若干字段则必须为这些字段手工创建DTO类型。如果是返回DTO类型的则无需在分部类封装方法了,直接使用导入的函数即可。
总结:如果不使用最后SELECT结果的话,则不必理会返回类型,将返回类型设置为“无”即可,当然我们封装的函数可以获取存储过程Return结果及OUTPUT类型的参数。所以上面例子代码可以删除存储过程中的Return前的Select语句,同时添加函数导入时指定返回类型为“无”。
相关文章推荐
- 调用EF的存储过程报“存储区数据提供程序返回的数据读取器所具有的列数对于所请求的查询不够”问题
- 程序调用查询数据存储过程的问题
- 微信小程序,请求php后台返回json数据多出隐藏字符问题
- Android 跨程序调用,返回数据获取不到的问题
- Linq 此提供程序只支持对返回实体或投影(包含所有标识列)的有序查询使用 问题的解决
- 【.net】DbProviderFactories找不到请求的 .Net Framework 数据提供程序。可能没有安装”的问题
- SQLite : 解决“找不到请求的 .Net Framework 数据提供程序。可能没有安装”的问题
- EF调用存储过程查询表中的部分字段,报数据读取器与指定的“AdventureWorksDWModel.Student”不兼容。某个类型为“Age”的成员在同名的数据读取器中没有对应的列。
- 【Mysql To EF】codefirst连接问题提供程序未返回 ProviderManifestToken 字符串
- 调用企业信息查询接口展示数据并对外提供接口遇到的问题
- 关于VS2005 调用WebService返回发送请求数据失败问题
- 一个提供数据存储和查询服务的分布式中间件需要考虑的一般问题
- c#Winform程序调用app.config文件配置数据库连接字符串 SQL Server文章目录 浅谈SQL Server中统计对于查询的影响 有关索引的DMV SQL Server中的执行引擎入门 【译】表变量和临时表的比较 对于表列数据类型选择的一点思考 SQL Server复制入门(一)----复制简介 操作系统中的进程与线程
- jQuery在异步请求数据返回后,调用$("selector").html(data.content);之后因为一些特殊字符或者',"不能显示内容的问题解决办法
- 解决“找不到请求的 .Net Framework 数据提供程序。可能没有安装”的问题
- “数据提供程序或其他服务返回 E_FAIL 状态” 的问题
- php实现post请求 接收android客户端json数据 存储数据库 并返回json
- 由于扩展配置问题而无法提供您请求的页面。如果该页面是脚本,请添加处理程序。如果应下载文件,请添加 MIME 映射。
- Flex中DataGrid通过存储在List中的JAVABEAN提供数据时候,数据不能正常显示的问题
- 程序中各种变量的存储位置和程序返回变量的问题