前言

本节我们来讲讲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. Python高手之路【六】python基础之字符串格式化

    Python的字符串格式化有两种方式: 百分号方式.format方式 百分号的方式相对来说比较老,而format方式则是比较先进的方式,企图替换古老的方式,目前两者并存.[PEP-3101] This ...

  2. 关于解决python线上问题的几种有效技术

    工作后好久没上博客园了,虽然不是很忙,但也没学生时代闲了.今天上博客园,发现好多的文章都是年终总结,想想是不是自己也应该总结下,不过现在还没想好,等想好了再写吧.今天写写自己在工作后用到的技术干货,争 ...

  3. .NET Core 首例 Office 开源跨平台组件(NPOI Core)

    前言 最近项目中,需要使用到 Excel 导出,找了一圈发现没有适用于 .NET Core的,不依赖Office和操作系统限制的 Office 组件,于是萌生了把 NPOI 适配并移植到 .NET C ...

  4. CYQ.Data、ASP.NET Aries 百家企业使用名单

    如果您或您所在的公司正在使用此框架,请联系左侧的扣扣,告知我信息,我将为您添加链接: 以下内容为已反馈的用户,(收集始于:2016-08-08),仅展示99家: 序号 企业名称 企业网址 备注 1 山 ...

  5. zookeeper源码分析之六session机制

    zookeeper中session意味着一个物理连接,客户端连接服务器成功之后,会发送一个连接型请求,此时就会有session 产生. session由sessionTracker产生的,sessio ...

  6. mysql进阶之存储过程

    往往看别人的代码会有这样的感慨: 看不懂 理还乱 是离愁 别是一番滋味在心头 为什么要使用存储过程? 在mysql开发中使用存储过程的理由: 当希望在不同的应用程序或平台上执行相同的函数,或者封装特定 ...

  7. 最长回文子串-LeetCode 5 Longest Palindromic Substring

    题目描述 Given a string S, find the longest palindromic substring in S. You may assume that the maximum ...

  8. 玩转Vim 编辑器

    一:VIM快速入门 1.vim模式介绍 以下介绍内容来自维基百科Vim 从vi演生出来的Vim具有多种模式,这种独特的设计容易使初学者产生混淆.几乎所有的编辑器都会有插入和执行命令两种模式,并且大多数 ...

  9. Java中常用集合操作

    一.Map 名值对存储的. 常用派生类HashMap类 添加: put(key,value)往集合里添加数据 删除: clear()删除所有 remove(key)清除单个,根据k来找 获取: siz ...

  10. Java 中获取类路径 classpath 的方法

    System.out.println("++++++++++++++++++++++++"); String path = System.getProperty("jav ...