LINQ的ORM功能中对使用sp_executesql语句的存储过程的支持

简介:
  
 
在实际的项目中,我们经常会碰到存储过程中需要使用sp_executesql语句的情形,如下:
    1  IF EXISTS ( SELECT * FROM sysobjects WHERE type = 'P' AND name = 'GetEmployeesByFilter')
    2     BEGIN
    3         DROP Procedure [GetEmployeesByFilter]
    4     END
    5 
    6 GO
    7 
    8  CREATE Procedure [GetEmployeesByFilter]
    9     (
   10         @EmployeeNo NVarChar(50) = NULL,
   11         @EmployeeName NVarChar(50) = NULL,
   12         @DepartmentId Int = NULL,
   13         @PositionId Int = NULL,
   14         @EmployeeManager Int = NULL,
   15         @BeginEmployeeEntryDate DateTime = NULL,
   16         @EndEmployeeEntryDate DateTime = NULL,
   17         @EmployeeStatus Int = NULL,
   18         @PageSize Int = NULL,
   19         @PageIndex Int = NULL,
   20         @RecordCount Int = NULL OUTPUT
   21     )
   22 
   23  AS
   24 
   25     BEGIN
   26         DECLARE @MinIndex Int
   27         DECLARE @MaxIndex Int
   28         SET @MinIndex = (@PageIndex - 1) * @PageSize + 1
   29         SET @MaxIndex = @MinIndex + @PageSize - 1
   30 
   31         DECLARE @Where NVarChar( MAX)
   32         SET @Where = '0 = 0'
   33         IF @EmployeeNo IS NOT NULL
   34             SET @Where = @Where + ' AND [EmployeeNo] LIKE ''%' + @EmployeeNo + '%'''
   35         IF @EmployeeName IS NOT NULL
   36             SET @Where = @Where + ' AND [EmployeeName] LIKE ''%' + @EmployeeName + '%'''
   37         IF @DepartmentId IS NOT NULL
   38             SET @Where = @Where + ' AND [DepartmentId] = ''' + CONVERT( NVarChar, @DepartmentId) + ''''
   39         IF @PositionId IS NOT NULL
   40             SET @Where = @Where + ' AND [PositionId] = ''' + CONVERT( NVarChar, @PositionId) + ''''
   41         IF @EmployeeManager IS NOT NULL
   42             SET @Where = @Where + ' AND [EmployeeManager] = ''' + CONVERT( NVarChar, @EmployeeManager) + ''''
   43         IF @BeginEmployeeEntryDate IS NOT NULL
   44             SET @Where = @Where + ' AND [EmployeeEntryDate] >= ''' + CONVERT( NVarChar, @BeginEmployeeEntryDate, 101) + ' ' + '00:00:00' + ''''
   45         IF @EndEmployeeEntryDate IS NOT NULL
   46             SET @Where = @Where + ' AND [EmployeeEntryDate] <= ''' + CONVERT( NVarChar, @EndEmployeeEntryDate, 101) + ' ' + '23:59:59' + ''''
   47         IF @EmployeeStatus IS NOT NULL
   48             SET @Where = @Where + ' AND [EmployeeStatus] = ''' + CONVERT( NVarChar, @EmployeeStatus) + ''''
   49 
   50         DECLARE @Record NVarChar( MAX)
   51         SET @Record = 'SELECT ROW_NUMBER() OVER(ORDER BY [EmployeeId]) AS [Index],
   52                               [EmployeeId],
   53                               [EmployeeNo],
   54                               [EmployeeName],
   55                               [DepartmentId],
   56                               [PositionId],
   57                               [EmployeeManager],
   58                               [EmployeeGender],
   59                               [EmployeeEntryDate],
   60                               [EmoplyeeBirthday],
   61                               [EmployeePhone],
   62                               [EmployeeEmail],
   63                               [EmployeeStatus]
   64                        FROM [Employee]
   65                        WHERE' + ' ' + @Where
   66 
   67         DECLARE @Sql NVarChar( MAX)
   68         SET @Sql = 'SELECT @RecordCount = COUNT(*)
   69                     FROM (' + @Record + ') DERIVEDTBL
   70 
   71                     SELECT [EmployeeId],
   72                            [EmployeeNo],
   73                            [EmployeeName],
   74                            [DepartmentId],
   75                            [PositionId],
   76                            [EmployeeManager],
   77                            [EmployeeGender],
   78                            [EmployeeEntryDate],
   79                            [EmoplyeeBirthday],
   80                            [EmployeePhone],
   81                            [EmployeeEmail],
   82                            [EmployeeStatus]
   83                     FROM (' + @Record + ') DERIVEDTBL
   84                     WHERE [Index] >= @MinIndex AND [Index] <= @MaxIndex'
   85 
   86         DECLARE @Parameter NVarChar( MAX)
   87         SET @Parameter = '@MinIndex Int, @MaxIndex Int, @RecordCount Int OUTPUT'
   88 
   89         EXEC sp_executesql @Sql, @Parameter, @MinIndex, @MaxIndex, @RecordCount OUTPUT
   90     END
   91 
   92 GO
但在这种情况下,LINQ往往不能正确识别:
    1      < Function Name =" dbo.GetEmployeesByFilter" Method =" GetEmployeesByFilter" >
    2          < Parameter Name =" EmployeeNo" Parameter =" employeeNo" Type =" System.String" DbType =" NVarChar(50)" />
    3          < Parameter Name =" EmployeeName" Parameter =" employeeName" Type =" System.String" DbType =" NVarChar(50)" />
    4          < Parameter Name =" DepartmentId" Parameter =" departmentId" Type =" System.Int32" DbType =" Int" />
    5          < Parameter Name =" PositionId" Parameter =" positionId" Type =" System.Int32" DbType =" Int" />
    6          < Parameter Name =" EmployeeManager" Parameter =" employeeManager" Type =" System.Int32" DbType =" Int" />
    7          < Parameter Name =" BeginEmployeeEntryDate" Parameter =" beginEmployeeEntryDate" Type =" System.DateTime" DbType =" DateTime" />
    8          < Parameter Name =" EndEmployeeEntryDate" Parameter =" endEmployeeEntryDate" Type =" System.DateTime" DbType =" DateTime" />
    9          < Parameter Name =" EmployeeStatus" Parameter =" employeeStatus" Type =" System.Int32" DbType =" Int" />
   10          < Parameter Name =" PageSize" Parameter =" pageSize" Type =" System.Int32" DbType =" Int" />
   11          < Parameter Name =" PageIndex" Parameter =" pageIndex" Type =" System.Int32" DbType =" Int" />
   12          < Parameter Name =" RecordCount" Parameter =" recordCount" Type =" System.Int32" DbType =" Int" Direction =" InOut" />
   13          < Return Type =" System.Int32" DbType =" Int" />
   14      </ Function >
这就是说,原本这个存储过程会返回一个结果集的,但LINQ会误认为返回的是一个Int32的值。
遇到这种情况,我们该怎么处理呢?这里提供两种解决方案:
1、直接更改DBML文件,将返回值改成一个空的结果集。
    1    < Function Name =" dbo.GetEmployeesByFilter" Method =" GetEmployeesByFilter" >
    2      < Parameter Name =" EmployeeNo" Parameter =" employeeNo" Type =" System.String" DbType =" NVarChar(50)" />
    3      < Parameter Name =" EmployeeName" Parameter =" employeeName" Type =" System.String" DbType =" NVarChar(50)" />
    4      < Parameter Name =" DepartmentId" Parameter =" departmentId" Type =" System.Int32" DbType =" Int" />
    5      < Parameter Name =" PositionId" Parameter =" positionId" Type =" System.Int32" DbType =" Int" />
    6      < Parameter Name =" EmployeeManager" Parameter =" employeeManager" Type =" System.Int32" DbType =" Int" />
    7      < Parameter Name =" BeginEmployeeEntryDate" Parameter =" beginEmployeeEntryDate" Type =" System.DateTime" DbType =" DateTime" />
    8      < Parameter Name =" EndEmployeeEntryDate" Parameter =" endEmployeeEntryDate" Type =" System.DateTime" DbType =" DateTime" />
    9      < Parameter Name =" EmployeeStatus" Parameter =" employeeStatus" Type =" System.Int32 &gt;" DbType =" Int" />
   10      < Parameter Name =" PageSize" Parameter =" pageSize" Type =" System.Int32" DbType =" Int" />
   11      < Parameter Name =" PageIndex" Parameter =" pageIndex" Type =" System.Int32" DbType =" Int" />
   12      < Parameter Name =" RecordCount" Parameter =" recordCount" Type =" System.Int32" DbType =" Int" Direction =" InOut" />
   13      < ElementType Name =" GetEmployeesByFilterResult" />
   14    </ Function >
然后再按照上一篇文章所说的方法处理即可。
2、保持存储过程GetEmployeesByFilter不变,再创建另外一个存储过程GetEmployeesByFilterCalling,然后在存储过程GetEmployeesByFilterCalling中调用存储过程GetEmployeesByFilter(EXEC GetEmployeesByFilter)。
(感谢Microsoft公司的Brandon Wang提供的这个方案。不过对不住的是,在我的系统中第一种方案用起来似乎更为方便些。)

本文出自 “Denny_Zhang” 博客,出处http://eallies.blog.51cto.com/375118/79030

posted on 2009-05-07 11:44 瞌睡
版权说明

  如果标题未标有<转载、转>等字则属于作者原创,欢迎转载,其版权归作者和博客园共有。
  作      者:温景良
  文章出处:http://wenjl520.cnblogs.com/  或  http://www.cnblogs.com/

分类: Linq
0
0
« 上一篇: 大型网站架构不得不考虑的10个问题 (转载)
» 下一篇: 微软公司的三道面试题目看了会有意想不到的收获
posted @ 2009-05-07 19:45 温景良(Jason) Views( 272) Comments( 0) Edit 收藏
 
相关文章
|
存储 .NET 开发框架
Linq to Entity调用存储过程【转】
http://www.cnblogs.com/chenxizhang/archive/2010/01/03/1638201.html学习交流群:364976091
838 0
|
SQL 存储 .NET
一步一步学Linq to sql(五):存储过程
普通存储过程 create proc sp_singleresultset as set nocount on select * from customers 首先在查询分析器运行下面的代码来创建一个存储过程sp_singleresultset。
795 0
|
3天前
|
存储 SQL 关系型数据库
[MySQL]存储过程
本文介绍了存储过程的概念、优点和缺点,并通过具体示例详细讲解了存储过程的创建、使用和调用方法。此外,还介绍了游标的定义和使用,帮助读者更好地理解和应用存储过程。文章旨在为读者提供一个学习和使用存储过程的实用指南。
38 18
[MySQL]存储过程
|
26天前
|
存储 SQL 关系型数据库
MySql数据库---存储过程
MySql数据库---存储过程
27 5
|
25天前
|
存储 关系型数据库 MySQL
MySQL 存储过程返回更新前记录
MySQL 存储过程返回更新前记录
39 3
|
25天前
|
存储 SQL 关系型数据库
MySQL 存储过程错误信息不打印在控制台
MySQL 存储过程错误信息不打印在控制台
36 1
|
3月前
|
存储 关系型数据库 MySQL
Mysql表结构同步存储过程(适用于模版表)
Mysql表结构同步存储过程(适用于模版表)
44 0
|
3月前
|
存储 SQL 关系型数据库
MySQL 创建存储过程注意项
MySQL 创建存储过程注意项
39 0

相关课程

更多