[译]DbContext API中使用SqlQuery和ExecuteSqlCommand获取存储过程的输入输出参数
水平有限,欢迎指正。
原文:http://blogs.msdn.com/b/diego/archive/2012/01/10/how-to-execute-stored-procedures-sqlquery-in-the-dbcontext-api.aspx
在 Entity Framework 4.1中引入的DbContext API暴露了一些新的方法用于提供透传原生SQL给数据库执行查询和命令,比如 Database.SqlQuery<T>, 以及 Database.ExecuteSqlCommand。
这些方法很重要不仅仅因为它们允许你执行自己的原生SQL查询,而且因为它们是当前你可以使用DbContext访问存储过程的主要方法,特别当你使用代码优先的开发模式。
就实现而言,它们是在EF 4.0中加入的ObjectContext.ExecuteStoreQuery<T> 和 ObjectContext.ExecuteStoreCommand 的更简单变种。不管怎么说,关于这些方法可以做什么看上去还是会有一些困惑,尤其是它们支持的查询语法。
简而言之我觉得以下几点可以说明这些方法是怎么工作的:
1、传递给方法的查询文本会被设置给来自底层ADO.NET提供程序的DbCommand对象。
2、DbCommand对象是通过设置CommandType属性值为CommandType.Text来执行的。
3、此外,如果方法会返回你之前传递的对象类型的结果(例如SqlQuery<T>),这个结果是基于DbDataReader返回的值所提取的。
你可以使用类似下面的语法,从一个存储过程返回的必要列中提取一个个人实体对象:
var idParam = new SqlParameter {
ParameterName = "id",
Value = };
var person = context.Database.SqlQuery<Person>(
"GetPerson @id",
idParam);
为了方便这些方法同时也接收普通的原始类型参数。你可以使用类似“{0}”的语法在查询语句中使用这些参数。
var person = context.Database.SqlQuery<Person>(
"SELECT * FROM dbo.People WHERE Id = {0}", id);
可是这些语法适用性有局限,而且可能你要做的一些事情需要更好的控制,像调用一个带输入输出参数的存储过程,或者参数不是基本类型,你必须使用数据源所支持的完整的SQL语法。
我想分享一个关于使用输入输出参数的简单例子,这样可以更好的举例说明。
在你的SQL Server数据库中创建一个(完整但没什么用)存储过程定义:
CREATE PROCEDURE [dbo].[GetPersonAndVoteCount]
(
@id int,
@voteCount int OUTPUT
)
AS
BEGIN
SELECT @voteCount = COUNT(*)
FROM dbo.Votes
WHERE PersonId = @id;
SELECT *
FROM dbo.People
WHERE Id = @id;
END
你可以写一段如下所示的代码执行它:
var idParam = new SqlParameter {
ParameterName = "id",
Value = };
var votesParam = new SqlParameter {
ParameterName = "voteCount",
Value = ,
Direction = ParameterDirection.Output };
var results = context.Database.SqlQuery<Person>(
"GetPersonAndVoteCount @id, @voteCount out",
idParam,
votesParam);
var person = results.Single();
var votes = (int)votesParam.Value;
在上面这段代码中有几个注意事项:
1、SqlQuery和ExecuteSqlCommand方法所支持的主要语法是被底层ADO.NET提供程序所支持的原生SQL语法。(有人在评论中提到SQL Server 2005必须在存储过程名前面加上EXEC关键字)。
2、DbCommand是使用CommandType.Text(相对于CommandType.StoredProcedure)来执行的,这意味着它不会自动为存储过程绑定参数,尽管如此你还是可以使用普通的SQL语法来执行存储过程。
3、你必须使用正确的语法来为存储过程传递一个输入输出参数,比如你需要在SQL语句中参数名称的后面增加一个“OUT”关键字。
4、输入和输出参数仅仅在使用实际的DbParameters类型的时候起作用(在这个例子中我们使用SqlParameters因为我们使用SQL Server),SqlQuery和ExecuteSqlCommand所支持的普通类型对象是不支持输入输出参数的。(译注:SqlQuery和ExecuteSqlCommand的参数要么全部是DbParameter参数,要么全部是普通类型对象)
5、在你访问输入输出参数你必须读整个返回结果(这个例子我们通过Single方法获取),但这是存储过程工作原理不是特定于EF的特性。
一旦你学会了,你可以使用提供程序特定参数和底层数据源的原生SQL语法,你能够获取更多和你使用ADO.NET相同的灵活性,但是使用ADO.NET无法获得重用同一个EF所维护的数据库连接的便利性和直接从查询结果中获取对象的能力。
[译]DbContext API中使用SqlQuery和ExecuteSqlCommand获取存储过程的输入输出参数的更多相关文章
- Entity Framework 6 Recipes 2nd Edition(9-3)译->找出Web API中发生了什么变化
9-3. 找出Web API中发生了什么变化 问题 想通过基于REST的Web API服务对数据库进行插入,删除和修改对象图,而不必为每个实体类编写单独的更新方法. 此外, 用EF6的Code Fri ...
- C#实现多级子目录Zip压缩解压实例 NET4.6下的UTC时间转换 [译]ASP.NET Core Web API 中使用Oracle数据库和Dapper看这篇就够了 asp.Net Core免费开源分布式异常日志收集框架Exceptionless安装配置以及简单使用图文教程 asp.net core异步进行新增操作并且需要判断某些字段是否重复的三种解决方案 .NET Core开发日志
C#实现多级子目录Zip压缩解压实例 参考 https://blog.csdn.net/lki_suidongdong/article/details/20942977 重点: 实现多级子目录的压缩, ...
- [译]ASP.NET Core Web API 中使用Oracle数据库和Dapper看这篇就够了
[译]ASP.NET Core Web API 中使用Oracle数据库和Dapper看这篇就够了 本文首发自:博客园 文章地址: https://www.cnblogs.com/yilezhu/p/ ...
- 译:DOM2中的高级事件处理(转)
17.2. DOM2中的高级事件处理(Advanced Event Handling with DOM Level 2) 译自:JavaScript: The Definitive Gu ...
- 在ASP.NET Web API中使用OData
http://www.alixixi.com/program/a/2015063094986.shtml 一.什么是ODataOData是一个开放的数据协议(Open Data Protocol)在A ...
- ASP.NET Web API中使用OData
在ASP.NET Web API中使用OData 一.什么是ODataOData是一个开放的数据协议(Open Data Protocol)在ASP.NET Web API中,对于CRUD(creat ...
- ASP.NET Web API中的Routing(路由)
[译]Routing in ASP.NET Web API 单击此处查看原文 本文阐述了ASP.NET Web API是如何将HTTP requests路由到controllers的. 如果你对ASP ...
- ASP.NET MVC和Web API中的Angular2 - 第1部分
下载源码 - 903.5 KB 内容 第1部分:Visual Studio 2017中的Angular2设置,基本CRUD应用程序,第三方模态弹出控件 第2部分:使用Angular2管道进行过滤/搜索 ...
- [译]async/await中使用阻塞式代码导致死锁 百万数据排序:优化的选择排序(堆排序)
[译]async/await中使用阻塞式代码导致死锁 这篇博文主要是讲解在async/await中使用阻塞式代码导致死锁的问题,以及如何避免出现这种死锁.内容主要是从作者Stephen Cleary的 ...
随机推荐
- 谈谈一些有趣的CSS题目(三)-- 层叠顺序与堆栈上下文知多少
开本系列,讨论一些有趣的 CSS 题目,抛开实用性而言,一些题目为了拓宽一下解决问题的思路,此外,涉及一些容易忽视的 CSS 细节. 解题不考虑兼容性,题目天马行空,想到什么说什么,如果解题中有你感觉 ...
- 【CSS进阶】伪元素的妙用--单标签之美
最近在研读 <CSS SECRET>(CSS揭秘)这本大作,对 CSS 有了更深层次的理解,折腾了下面这个项目: CSS3奇思妙想 -- Demo (请用 Chrome 浏览器打开,非常值 ...
- 15个关于Chrome的开发必备小技巧[译]
谷歌Chrome,是当前最流行且被众多web开发人员使用的浏览器.最快六周就更新发布一次以及伴随着它不断强大的开发组件,使得Chrome成为你必备的开发工具.例如,在线编辑CSS,console以及d ...
- 【Reading Note】算法读书杂记
1 排序 排序基本信息 稳定性:排序前大的数在排序后,大的数依然保持不变就是稳定排序,反之不稳定 内外排序:根据待排序的记录是否放在内存里面区分的.诸如:插入排序(直接插入&希尔).交换排序( ...
- CentOS7使用firewalld打开关闭防火墙与端口(转载)
1.firewalld的基本使用 启动: systemctl start firewalld 查看状态: systemctl status firewalld 停止: systemctl disabl ...
- 自己来实现一个简易的OCR
来做个简易的字符识别 ,既然是简易的 那么我们就不能用任何的第三方库 .啥谷歌的 tesseract-ocr, opencv 之类的 那些玩意是叼 至少图像处理 机器视觉这类课题对我这种高中没毕业的人 ...
- IL异常处理
异常处理在程序中也算是比较重要的一部分了,IL异常处理在C#里面实现会用到一些新的方法 1.BeginExceptionBlock:异常块代码开始,相当于try,但是感觉又不太像 2.EndExcep ...
- Java实现FTP文件与文件夹的上传和下载
Java实现FTP文件与文件夹的上传和下载 FTP 是File Transfer Protocol(文件传输协议)的英文简称,而中文简称为"文传协议".用于Internet上的控制 ...
- Atitit.软件开发的三层结构isv金字塔模型
Atitit.软件开发的三层结构isv金字塔模型 第一层,Implements 层,着重与功能的实现.. 第二次,spec层,理论层,设计规范,接口,等.流程.方法论 顶层,val层,价值观层,原则, ...
- Linux实战教学笔记03:操作系统发展历程及系统版本选择
标签(空格分隔): Linux实战教学笔记-陈思齐 第1章 Linux简介 1.1 什么是操作系统? 简单讲:操作系统就是一个人与计算机硬件的中介. 操作系统,英文名称Operating System ...