前言

本节我们来讲讲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的更多相关文章

  1. EntityFramework Core Raw Query再叙注意事项后续

    前言 话说通过EntityFramwork Core进行原始查询又出问题,且听我娓娓道来. EntityFramework Core Raw Query后续 当我们进行复杂查询时我们会通过原始查询来进 ...

  2. EntityFramework Core Raw Query再叙注意事项

    前言 最近一直比较忙没有太多时间去更新博客,接下来会一直持续发表相关内容博客,上一篇我们讲到了EF Core中的原始查询,这节我们再来叙述一下原始查询,本文是基于在项目当中用到时发现的问题. 话题 我 ...

  3. EntityFramework Core 2.0执行原始查询如何防止SQL注入?

    前言 接下来一段时间我们来讲讲EntityFramework Core基础,精简的内容,深入浅出,希望为想学习EntityFramework Core的童鞋提供一点帮助. EntityFramewor ...

  4. 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 ...

  5. 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平台下, ...

  6. EntityFramework 7 更名为EntityFramework Core(预发布状态)

    前言 最近很少去学习和探索新的东西,尤其是之前一直比较关注的EF领域,本身不太懒,但是苦于环境比较影响自身的心情,所以迟迟没有下笔,但是不去学习感觉在精神层面缺少点什么,同时也有园友说EF又更新了,要 ...

  7. EntityFramework Core技术线路(EF7已经更名为EF Core,并于2016年6月底发布)

    官方文档英文地址:https://github.com/aspnet/EntityFramework/wiki/Roadmap 历经延期和更名,新版本的实体框架终于要和大家见面了,虽然还有点害羞.请大 ...

  8. [转]EntityFramework Core技术线路(EF7已经更名为EF Core,并于2016年6月底发布)

    本文转自:http://www.cnblogs.com/VolcanoCloud/p/5572408.html 官方文档英文地址:https://github.com/aspnet/EntityFra ...

  9. 神马玩意,EntityFramework Core 1.1又更新了?走,赶紧去围观

    前言 哦,不搞SQL了么,当然会继续,周末会继续更新,估计写完还得几十篇,但是我会坚持把SQL更新完毕,绝不会烂尾,后续很长一段时间没更新的话,不要想我,那说明我是学习新的技能去了,那就是学习英语,本 ...

随机推荐

  1. Asp.net Boilerplate之AbpSession扩展

    当前Abp版本1.2,项目类型为MVC5. 以属性的形式扩展AbpSession,并在"记住我"后,下次自动登录也能获取到扩展属性的值,版权归"角落的白板报"所 ...

  2. 一篇文章看懂TPCx-BB(大数据基准测试工具)源码

    TPCx-BB是大数据基准测试工具,它通过模拟零售商的30个应用场景,执行30个查询来衡量基于Hadoop的大数据系统的包括硬件和软件的性能.其中一些场景还用到了机器学习算法(聚类.线性回归等).为了 ...

  3. ASP.NET MVC with Entity Framework and CSS一书翻译系列文章之第一章:创建基本的MVC Web站点

    在这一章中,我们将学习如何使用基架快速搭建和运行一个简单的Microsoft ASP.NET MVC Web站点.在我们马上投入学习和编码之前,我们首先了解一些有关ASP.NET MVC和Entity ...

  4. 终端mysql Operation not permitted错误解决方案

    前言 前段时间装mysql,就遇到了ln: /usr/bin/mysql: Operation not permitted的错误,网上好多方法都过时了,下边是我的解决方法 原因 这是因为苹果在OS X ...

  5. [原]Cachedb 网络模块文档

    Cachedb 网络模块文档 整体结构 多路复用 (epoll 模块) 事件驱动 (事件封装) 缓冲管理 (上层buffer管理) 设计思想 层次化的设计,每一个模块只调用上一个模块的接口,并将耦合聚 ...

  6. SharePoint 2013: A feature with ID has already been installed in this farm

    使用Visual Studio 2013创建一个可视web 部件,当右击项目选择"部署"时报错: "Error occurred in deployment step ' ...

  7. iOS之判断手机号码、邮箱格式是否正确

    //判断手机号码格式是否正确 + (BOOL)valiMobile:(NSString *)mobile{     mobile = [mobile stringByReplacingOccurren ...

  8. 如何理解MySQL中auto_increment?

    1.auto_increment用于主键自动增长.比如从1开始增长,当把第一条数据删除,再插入第二条数据时,主键值为2,不是1.

  9. 第13章 Linux日志管理

    1. 日志管理 (1)简介 在CentOS 6.x中日志服务己经由rsyslogd取代了原先的syslogd服务.rsyslogd日志服务更加先进,功能更多.但是不论该服务的使用,还是日志文件的格式其 ...

  10. C#(或者说.NET/Mono)能做的那些事

    不做语言之争,只陈述事实: 1.桌面软件与服务 不仅是在Windows上,有了开源的Mono,在Apple Mac和Linux(如:Ubuntu)上也有C#的施展天地.并且还可以通过mkbundle工 ...