使用EntityFramework可以很方便的与数据库打交道,但是对于存储过程,返回类型很让人纠结,默认只返回受影响的行数,而我们在使用存储过程时往往是会返回一串的数据或者一个表。那有没有什么方法呢?
我们知道在SQL2008是支持表类型的,如果存储过程在执行完成后返回了一个表类型,在EF端再接收一下,那是不是就可以了呢?事实证明是可行的。我们需要分几个步骤。
1.在数据库中建立一个表类型,比如叫KEY_VALUE类型。
-- Create the data type CREATE TYPE KEY_VALUE AS TABLE ( [Key] NVARCHAR(50), [Value] NVARCHAR(max), [Remark] NVARCHAR (max) ) GO如下图
2.存储过程
假定我们需要传入一个字符串的过滤条件,那么我们的存储过程可以定义一个参数,之后再拼接成SQL,使用EXEC来执行,同时把结果存入到表类型变量中。
CREATE PROCEDURE [dbo].[QueryStudent] @whereStr NVARCHAR(MAX) --根据需要定义的where条件 AS BEGIN DECLARE @temp_table KEY_VALUE DECLARE @sql NVARCHAR(MAX) SET @sql=' SELECT st_guid AS [Key], st_name AS [Value],st_hobby AS [Remark] FROM student WHERE '+@whereStr INSERT INTO @temp_table EXEC(@sql) SELECT [Key] AS [guid],[Value] AS [name],[Remark] AS [hobby] FROM @temp_table END3.EF端
EF端连到数据库后,将存储过程QueryStudent加入到模型中,结果如下图
在存储过程中我们知道返回的是一个表类型KEY_VALUE,其数据字段有guid,name,hobby,所以我们需要建立一个相对应的复杂类型来接收这个返回结果,步骤如下图
在添加新的复杂类型之后,命名为QueryStudent_Result,同时把guid、hobby、name三个字段都设置为string类型。
在函数导入下找到QueryStudent然后双击,如下图
将“返回以下的内容集合”设置为刚刚添加的复杂类型QueryStudent_Result,点击确定即可。
4.调用
调用示例代码如下
DBDemoEntities dbContext = new DBDemoEntities(); var data = dbContext.QueryStudent(" st_name='张三' ").ToList(); string str = $"{nameof(QueryStudent_Result.guid)}={data[0].guid}," +$"{ nameof(QueryStudent_Result.name)}={ data[0].name}," + $"{ nameof(QueryStudent_Result.hobby)}={ data[0].hobby},";结果如下图
至此,EntityFramework调用存储过程返回结果的接收就完成了。如果是EF6.0的,在添加模型的时候会直接生成QueryStudent_Result的类型,无须再单独建立。
转载请注明出处。