博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
综合应用WPF/WCF/WF/LINQ之十三:LINQ的ORM功能中对使用sp_executesql语句的存储过程的支持...
阅读量:6933 次
发布时间:2019-06-27

本文共 6189 字,大约阅读时间需要 20 分钟。

  在实际的项目中,我们经常会碰到存储过程中需要使用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提供的这个方案。不过对不住的是,在我的系统中第一种方案用起来似乎更为方便些。)
本文转自 Eallies 51CTO博客,原文链接:http://blog.51cto.com/eallies/79030,如需转载请自行联系原作者
你可能感兴趣的文章
js logger
查看>>
hdu6376 度度熊剪纸条 思维
查看>>
清空日志的三种方法
查看>>
传输文件过程中遇到异常被中断
查看>>
JBPM对象主键生成机制
查看>>
11-08笔记图
查看>>
接口里面的静态方法--痒啊
查看>>
mongodb分享(二)
查看>>
template模板的使用方法
查看>>
想成为一个高效的Web开发者吗?来看看大牛分享的经验吧~ #精选JAVASCRIPT前端开发...
查看>>
删除某个文件夹下的所有文件
查看>>
多线程 -- 实现秒抓
查看>>
1032 Sharing
查看>>
Leetcode | Minimum/Maximum Depth of Binary Tree
查看>>
引水工程
查看>>
centos 7 安装tomcat
查看>>
UIViewController的生命周期及iOS程序执行顺序
查看>>
LINUX C: 获取本地指定网卡的IP地址
查看>>
Centos 常用系统命令
查看>>
本地yum源建立
查看>>