前言

本节我们来讲讲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. Unity3d入门 - 关于unity工具的熟悉

    上周由于工作内容较多,花在unity上学习的时间不多,但总归还是学习了一些东西,内容如下: .1 根据相关的教程在mac上安装了unity. .2 学习了unity的主要的工具分布和对应工具的相关的功 ...

  2. 关于textview显示特殊符号居中的问题

    话说这是2017年的第一篇博客,也是一篇技术博客.先从简单的一篇解决问题开始吧,千里之行,始于足下! ------------------------------------------------- ...

  3. .NET 基础 一步步 一幕幕[面向对象之方法、方法的重载、方法的重写、方法的递归]

    方法.方法的重载.方法的重写.方法的递归 方法: 将一堆代码进行重用的一种机制. 语法: [访问修饰符] 返回类型 <方法名>(参数列表){ 方法主体: } 返回值类型:如果不需要写返回值 ...

  4. WinForm 天猫2013双11自动抢红包【源码下载】

    1. 正确获取红包流程 2. 软件介绍 2.1 效果图: 2.2 功能介绍 2.2.1 账号登录 页面开始时,会载入这个网站:https://login.taobao.com/member/login ...

  5. 利用apply()或者rest参数来实现用数组传递函数参数

    关于call()和apply()的用法,MDN文档里写的非常清晰明白,在这里就不多做记录了. https://developer.mozilla.org/zh-CN/docs/Web/JavaScri ...

  6. VS2015使用scanf报错的解决方案

    1.在程序最前面加: #define _CRT_SECURE_NO_DEPRECATE 2.在程序最前面加: #pragma warning(disable:4996) 3.把scanf改为scanf ...

  7. ES6之变量常量字符串数值

    ECMAScript 6 是 JavaScript 语言的最新一代标准,当前标准已于 2015 年 6 月正式发布,故又称 ECMAScript 2015. ES6对数据类型进行了一些扩展 在js中使 ...

  8. Android Butterknife 8.4.0 使用方法总结

    转载请标明出处:http://www.cnblogs.com/zhaoyanjun/p/6016341.html 本文出自[赵彦军的博客] 前言 ButterKnife 简介 ButterKnife是 ...

  9. AFN解析器里的坑

    AFN框架是用来用来发送网络请求的,它的好处是可以自动给你解析JSON数据,还可以发送带参数的请求AFN框架还可以监测当前的网络状态,还支持HTTPS请求,分别对用的类为AFNetworkReacha ...

  10. Spark的StandAlone模式原理和安装、Spark-on-YARN的理解

    Spark是一个内存迭代式运算框架,通过RDD来描述数据从哪里来,数据用那个算子计算,计算完的数据保存到哪里,RDD之间的依赖关系.他只是一个运算框架,和storm一样只做运算,不做存储. Spark ...