综合应用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,如需转载请自行联系原作者

目录
相关文章
|
3月前
|
C# 机器学习/深度学习 搜索推荐
WPF与机器学习的完美邂逅:手把手教你打造一个具有智能推荐功能的现代桌面应用——从理论到实践的全方位指南,让你的应用瞬间变得高大上且智能无比
【8月更文挑战第31天】本文详细介绍如何在Windows Presentation Foundation(WPF)应用中集成机器学习功能,以开发具备智能化特性的桌面应用。通过使用Microsoft的ML.NET框架,本文演示了从安装NuGet包、准备数据集、训练推荐系统模型到最终将模型集成到WPF应用中的全过程。具体示例代码展示了如何基于用户行为数据训练模型,并实现实时推荐功能。这为WPF开发者提供了宝贵的实践指导。
42 0
|
3月前
|
开发者 C# UED
WPF与多媒体:解锁音频视频播放新姿势——从界面设计到代码实践,全方位教你如何在WPF应用中集成流畅的多媒体功能
【8月更文挑战第31天】本文以随笔形式介绍了如何在WPF应用中集成音频和视频播放功能。通过使用MediaElement控件,开发者能轻松创建多媒体应用程序。文章详细展示了从创建WPF项目到设计UI及实现媒体控制逻辑的过程,并提供了完整的示例代码。此外,还介绍了如何添加进度条等额外功能以增强用户体验。希望本文能为WPF开发者提供实用的技术指导与灵感。
140 0
|
3月前
|
存储 开发者 C#
WPF与邮件发送:教你如何在Windows Presentation Foundation应用中无缝集成电子邮件功能——从界面设计到代码实现,全面解析邮件发送的每一个细节密武器!
【8月更文挑战第31天】本文探讨了如何在Windows Presentation Foundation(WPF)应用中集成电子邮件发送功能,详细介绍了从创建WPF项目到设计用户界面的全过程,并通过具体示例代码展示了如何使用`System.Net.Mail`命名空间中的`SmtpClient`和`MailMessage`类来实现邮件发送逻辑。文章还强调了安全性和错误处理的重要性,提供了实用的异常捕获代码片段,旨在帮助WPF开发者更好地掌握邮件发送技术,提升应用程序的功能性与用户体验。
56 0
|
3月前
|
API C# Shell
WPF与Windows Shell完美融合:深入解析文件系统操作技巧——从基本文件管理到高级Shell功能调用,全面掌握WPF中的文件处理艺术
【8月更文挑战第31天】Windows Presentation Foundation (WPF) 是 .NET Framework 的关键组件,用于构建 Windows 桌面应用程序。WPF 提供了丰富的功能来创建美观且功能强大的用户界面。本文通过问题解答的形式,探讨了如何在 WPF 应用中集成 Windows Shell 功能,并通过具体示例代码展示了文件系统的操作方法,包括列出目录下的所有文件、创建和删除文件、移动和复制文件以及打开文件夹或文件等。
75 0
|
3月前
|
C# Windows 监控
WPF应用跨界成长秘籍:深度揭秘如何与Windows服务完美交互,扩展功能无界限!
【8月更文挑战第31天】WPF(Windows Presentation Foundation)是 .NET 框架下的图形界面技术,具有丰富的界面设计和灵活的客户端功能。在某些场景下,WPF 应用需与 Windows 服务交互以实现后台任务处理、系统监控等功能。本文探讨了两者交互的方法,并通过示例代码展示了如何扩展 WPF 应用的功能。首先介绍了 Windows 服务的基础知识,然后阐述了创建 Windows 服务、设计通信接口及 WPF 客户端调用服务的具体步骤。通过合理的交互设计,WPF 应用可获得更强的后台处理能力和系统级操作权限,提升应用的整体性能。
99 0
|
3月前
|
前端开发 C# 容器
WPF/C#:实现导航功能
WPF/C#:实现导航功能
64 0
|
开发框架 前端开发 JavaScript
WPF+ASP.NET SignalR实现简易在线聊天功能
WPF+ASP.NET SignalR实现简易在线聊天功能
208 0
|
自然语言处理 编译器 C#
【WPF】实现动态切换语言(国际化)以及动态换肤功能
以下内容,手把手从搭建到最终实现,完成多语言切换以及换装功能。
441 0
【WPF】实现动态切换语言(国际化)以及动态换肤功能
|
前端开发 C# 图形学
【WPF】WPF开发用户控件、用户控件属性依赖DependencyProperty实现双向绑定、以及自定义实现Command双向绑定功能演示
Wpf开发过程中,最经常使用的功能之一,就是用户控件(UserControl)了。用户控件可以用于开发用户自己的控件进行使用,甚至可以用于打造一套属于自己的UI框架。依赖属性(DependencyProperty)是为用户控件提供可支持双向绑定的必备技巧之一,同样用处也非常广泛。
937 0
【WPF】WPF开发用户控件、用户控件属性依赖DependencyProperty实现双向绑定、以及自定义实现Command双向绑定功能演示
|
XML Java 程序员
WPF使用AvalonEdit实现代码高亮显示、搜索、替换功能
很多工程软件拥有自己定义的脚本语言,作为程序员用惯了具有高亮显示和智能提示功能的编辑器,所以针对特定的脚本自己开发一个编辑器。主要采用WPF、C#语言以及AvalonEdit控件。
WPF使用AvalonEdit实现代码高亮显示、搜索、替换功能