EntityFramework Core Raw SQL
前言
本节我们来讲讲EF Core中的原始查询,目前在项目中对于简单的查询直接通过EF就可以解决,但是涉及到多表查询时为了一步到位就采用了原始查询的方式进行。下面我们一起来看看。
EntityFramework Core Raw SQL
基础查询(执行SQL和存储过程)
啥也不说了,拿起键盘就是干,如下:
public class HomeController : Controller
{
private IBlogRepository _blogRepository;
public HomeController(IBlogRepository blogRepository)
{
_blogRepository = blogRepository;
}
public IActionResult Index()
{
var list = _blogRepository.GetList();
return Ok();
}
}
public class BlogRepository : EntityBaseRepository<Blog>,
IBlogRepository
{
private EFCoreContext _efCoreContext;
public BlogRepository(EFCoreContext efCoreContext) : base(efCoreContext)
{
_efCoreContext = efCoreContext;
} public IEnumerable<Blog> GetList()
{
var iQueryTable = _efCoreContext.Set<Blog>().
FromSql("select * from Blog");
return iQueryTable.ToList();
}
}

下面我们来看看存储过程。
CREATE PROCEDURE dbo.GetBlogList
AS
BEGIN
SELECT * FROM dbo.Blog
END
GO
public IEnumerable<Blog> GetList()
{
var iQueryTable = _efCoreContext.Set<Blog>().
FromSql("EXECUTE dbo.GetBlogList");
return iQueryTable.ToList();
}
参数查询
利用参数化存储过程查询。
ALTER PROCEDURE [dbo].[GetBlogList]
@id INT
AS
BEGIN
SELECT * FROM dbo.Blog WHERE Id = @id
END
结果利用FromSql就变成了如下:
public IEnumerable<Blog> GetList()
{
var Id = new SqlParameter("Id", "");
var iQueryTable = _efCoreContext.Set<Blog>().
FromSql("EXEC dbo.GetBlogList {0}", 1);
return iQueryTable.ToList();
}
上述是利用string.format的形式来传参,我们也可以利用SqlParameter来传参,如下:
public IEnumerable<Blog> GetList()
{
var Id = new SqlParameter("Id", "");
var iQueryTable = _efCoreContext.Set<Blog>().
FromSql("EXEC dbo.GetBlogList @id", Id);
return iQueryTable.ToList();
}
我们通过开启调试,可以清晰看到执行的存储过程。

通过如上我们知道参数化查询有两种形式,下面我们再来看看linq查询。
linq查询
上述我们演示一直直接使用FromSql,其实在此之后我们可以继续通过linq来进行查询,如下:
public IEnumerable<Blog> GetList()
{
var Id = new SqlParameter("Id", "");
var iQueryTable = _efCoreContext.Set<Blog>().
FromSql("EXEC dbo.GetBlogList @id", Id).Where(d => d.Name == "efcore2");
return iQueryTable.ToList();
}
之前我们映射了Blog和Post之间的关系,这里我们只能查询出Blog表的数据,通过对上述linq的讲解,我们完全可以通过inlcude来显式加载Post表数据,如下:
public IEnumerable<Blog> GetList()
{
var Id = new SqlParameter("Id", "");
var iQueryTable = _efCoreContext.Set<Blog>().
FromSql("EXEC dbo.GetBlogList @id", Id).Include(d => d.Posts);
return iQueryTable.ToList();
}

好吧,明确告诉我们对于存储过程是不支持Inlude操作的,所以要想Include我们只能进行简单的查询,如下:
public IEnumerable<Blog> GetList()
{
var iQueryTable = _efCoreContext.Set<Blog>().
FromSql("select * from blog").Include(d => d.Posts);
return iQueryTable.ToList();
}
查找官网资料时发现居然对表值函数(TVF)是可以Include的,创建内嵌表值函数如下:
USE [EFCoreDb]
GO IF OBJECT_ID('dbo.GetBlog') IS NOT NULL
DROP FUNCTION dbo.GetBlog;
GO CREATE FUNCTION dbo.GetBlog
(@Name VARCHAR(max)) RETURNS TABLE WITH SCHEMABINDING
AS
RETURN
SELECT Id, Name, Url FROM dbo.Blog WHERE Name = @Name
GO
调用如下:
public IEnumerable<Blog> GetList()
{
var name = "efcore2";
var iQueryTable = _efCoreContext.Set<Blog>().
FromSql("select * from [dbo].[GetBlog] {0}", name).Include(d => d.Posts);
return iQueryTable.ToList();
}
结果出乎意料的出现语法错误:

通过SQL Server Profiler查看发送的SQL语句如下:

这能不错么,官网给的示例也是和上述一样,如下:

只是按照和他一样的搬过来了,未曾想太多,还是粗心大意了,想了好一会,按照我们正常调用表值函数即可,我们需要用括号括起来才行,如下:
public IEnumerable<Blog> GetList()
{
var name = "efcore2";
var iQueryTable = _efCoreContext.Set<Blog>().
FromSql("select * from [dbo].[GetBlog] ({0})", name).Include(d => d.Posts);
return iQueryTable.ToList();
}
上述将[dbo.GetBlog]和({0})隔开和挨着都可以。这个时候才不会出现语法错误。执行的SQL如下才是正确的。

好了,到了这里关于EF Core中原始查询我们就告一段落了,其中还有一个知识点未谈及到,在EF Core我们可以直接通过底层的ADO.NET来进行查询,我们来看下:
底层ADO.NET查询
public IEnumerable<Blog> GetList()
{
var list = new List<Blog>();
using (var connection = _efCoreContext.Database.GetDbConnection())
{
connection.Open(); using (var command = connection.CreateCommand())
{
command.CommandText = "SELECT * FROM dbo.Blog"; using (SqlDataReader reader = command.ExecuteReader() as SqlDataReader)
{
while (reader.Read())
{
var blog = new Blog();
blog.Id = Convert.ToInt32(reader["Id"]);
blog.Name = reader["Name"].ToString();
blog.Url = reader["Url"].ToString();
list.Add(blog);
}
}
}
}
return list;
}

总结
我们本节讲述了EF Core中的原始查询,相比较之前EF版本的原始查询使用更加灵活了一点,但是缺陷还是展露无遗,依然只能查出所有的列且必须匹配,同时呢,若我们想执行事务,目前还不支持底层的TranscationScope仅仅支持BeginTranscation。
EntityFramework Core Raw SQL的更多相关文章
- EntityFramework Core Raw Query再叙注意事项后续
前言 话说通过EntityFramwork Core进行原始查询又出问题,且听我娓娓道来. EntityFramework Core Raw Query后续 当我们进行复杂查询时我们会通过原始查询来进 ...
- EntityFramework Core Raw Query再叙注意事项
前言 最近一直比较忙没有太多时间去更新博客,接下来会一直持续发表相关内容博客,上一篇我们讲到了EF Core中的原始查询,这节我们再来叙述一下原始查询,本文是基于在项目当中用到时发现的问题. 话题 我 ...
- EntityFramework Core 2.0执行原始查询如何防止SQL注入?
前言 接下来一段时间我们来讲讲EntityFramework Core基础,精简的内容,深入浅出,希望为想学习EntityFramework Core的童鞋提供一点帮助. EntityFramewor ...
- EF Core 2.1 Raw SQL Queries (转自MSDN)
Entity Framework Core allows you to drop down to raw SQL queries when working with a relational data ...
- Webservice WCF WebApi 前端数据可视化 前端数据可视化 C# asp.net PhoneGap html5 C# Where 网站分布式开发简介 EntityFramework Core依赖注入上下文方式不同造成内存泄漏了解一下? SQL Server之深入理解STUFF 你必须知道的EntityFramework 6.x和EntityFramework Cor
Webservice WCF WebApi 注明:改编加组合 在.net平台下,有大量的技术让你创建一个HTTP服务,像Web Service,WCF,现在又出了Web API.在.net平台下, ...
- EntityFramework 7 更名为EntityFramework Core(预发布状态)
前言 最近很少去学习和探索新的东西,尤其是之前一直比较关注的EF领域,本身不太懒,但是苦于环境比较影响自身的心情,所以迟迟没有下笔,但是不去学习感觉在精神层面缺少点什么,同时也有园友说EF又更新了,要 ...
- EntityFramework Core技术线路(EF7已经更名为EF Core,并于2016年6月底发布)
官方文档英文地址:https://github.com/aspnet/EntityFramework/wiki/Roadmap 历经延期和更名,新版本的实体框架终于要和大家见面了,虽然还有点害羞.请大 ...
- [转]EntityFramework Core技术线路(EF7已经更名为EF Core,并于2016年6月底发布)
本文转自:http://www.cnblogs.com/VolcanoCloud/p/5572408.html 官方文档英文地址:https://github.com/aspnet/EntityFra ...
- 神马玩意,EntityFramework Core 1.1又更新了?走,赶紧去围观
前言 哦,不搞SQL了么,当然会继续,周末会继续更新,估计写完还得几十篇,但是我会坚持把SQL更新完毕,绝不会烂尾,后续很长一段时间没更新的话,不要想我,那说明我是学习新的技能去了,那就是学习英语,本 ...
随机推荐
- 对Castle Windsor的Resolve方法的解析时new对象的探讨
依赖注入框架Castle Windsor从容器里解析一个实例时(也就是调用Resolve方法),是通过调用待解析对象的构造函数new一个对象并返回,那么问题是:它是调用哪个构造函数呢? 无参的构造函数 ...
- 将 instance 部署到 OVS Local Network - 每天5分钟玩转 OpenStack(130)
上一节创建了 OVS 本地网络 first_local_net,今天我们会部署一个 instance 到该网络并分析网络结构.launch 一个 instance,选择 first_local_net ...
- C#中将DataTable导出为HTML的方法
今天我要向大家分享一种将DataTable导出为到HTML格式的方法.有时我们需要HTML格式的输出数据, 以下代码就可以帮助我们达到目的,. 首先,我们要绑定DataTable和 DataGridV ...
- JavaScript中事件处理
先看看下面一道题目,请评价以下代码并给出改进意见: if (window.addEventListener) {//标准浏览器 var addListener = function(el, type, ...
- 彻底搞懂Javascript的“==”
本文转载自:@manxisuo的<通过一张简单的图,让你彻底地.永久地搞懂JS的==运算>. 大家知道,==是JavaScript中比较复杂的一个运算符.它的运算规则奇怪,容让人犯错,从而 ...
- Android中Fragment和ViewPager那点事儿(仿微信APP)
在之前的博文<Android中使用ViewPager实现屏幕页面切换和引导页效果实现>和<Android中Fragment的两种创建方式>以及<Android中Fragm ...
- 让你从零开始学会写爬虫的5个教程(Python)
写爬虫总是非常吸引IT学习者,毕竟光听起来就很酷炫极客,我也知道很多人学完基础知识之后,第一个项目开发就是自己写一个爬虫玩玩. 其实懂了之后,写个爬虫脚本是很简单的,但是对于新手来说却并不是那么容易. ...
- Linux C语言解析并显示.bmp格式图片
/************************* *bmp.h文件 *************************/ #ifndef __BMP_H__ #define __BMP_H__ # ...
- servlet使用入门
创建web工程servlet,然后新建TestServlet.java package com.xmyself.servlet; import java.io.IOException; import ...
- 【腾讯bugly干货分享】微信Android热补丁实践演进之路
本文来自于腾讯bugly开发者社区,非经作者同意,请勿转载,原文地址:http://bugly.qq.com/bbs/forum.php?mod=viewthread&tid=1264& ...