综合应用WPF/WCF/WF/LINQ之十三:LINQ的ORM功能中对使用sp_executesql语句的存储过程的支持-阿里云开发者社区

开发者社区> 余二五> 正文

综合应用WPF/WCF/WF/LINQ之十三: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提供的这个方案。不过对不住的是,在我的系统中第一种方案用起来似乎更为方便些。)




本文转自 Eallies 51CTO博客,原文链接:http://blog.51cto.com/eallies/79030,如需转载请自行联系原作者

版权声明:本文内容由阿里云实名注册用户自发贡献,版权归原作者所有,阿里云开发者社区不拥有其著作权,亦不承担相应法律责任。具体规则请查看《阿里云开发者社区用户服务协议》和《阿里云开发者社区知识产权保护指引》。如果您发现本社区中有涉嫌抄袭的内容,填写侵权投诉表单进行举报,一经查实,本社区将立刻删除涉嫌侵权内容。

相关文章
Android Studio 通过一个登录功能介绍SQLite数据库的使用
前言:         SQLite简介:是一款轻型的数据库,是遵守ACID的关系型数据库管理系统,它包含在一个相对小的C库中。它是D.RichardHipp建立的公有领域项目。它的设计目标是嵌入式的,而且目前已经在很多嵌入式产品中使用了它,它占用资源非常的低,在嵌入式设备中,可能只需要几百K的内存就够了。
4227 0
App Inspector-iOS真机功能详解
前言: App Inspector:浏览器端的移动设备 UI 查看器,使用树状态结构查看 UI 布局,自动生成 XPaths。官网:https://macacajs.
1518 0
django的orm中F对象的使用
今天不巧就用上了。 就是将数据库的字段,自增1的场景。 from django.db.models import F DeployPool.objects.filter(name=deployversion_id).
1147 0
Reflection.Emit的使用场景、工具包及示例总结
最近处理一个业务需要动态的生成一些业务模型和库,使用到了Emit的处理,相关的资料整理一下供参考。 Reflection.Emit目的 使用的场景: 应用中自定义一个自己的语言 运行中动态的创建类型、模块等,同时又需要提高效率(可以动态编译一次,然后就不用再处理了) 延迟绑定对象的使用,在和Office这类的软件时会用到 动态插件系统等 … System.
967 0
新功能初探 | RDS MySQL 8.0 支持 DML 语句 returning
MySQL 对于 statement 执行结果报文通常分为两类 Resultset 和 OK/ERR,针对 DML 语句则返回OK/ERR 报文,其中包括几个影响记录,扫描记录等属性。
6898 0
+关注
20382
文章
0
问答
文章排行榜
最热
最新
相关电子书
更多
《2021云上架构与运维峰会演讲合集》
立即下载
《零基础CSS入门教程》
立即下载
《零基础HTML入门教程》
立即下载