asp.net core系列 33 EF查询数据 (2)
一. 原生SQL查询
接着上篇讲。通过 Entity Framework Core 可以在使用关系数据库时下降到原始 SQL 查询。 在无法使用 LINQ 表达要执行的查询时,或因使用 LINQ 查询而导致低效的 SQL 查询时非常有用。 原始 SQL 查询可返回实体类型,或者从 EF Core 2.1 开始,可返回模型中的查询类型。
1.1 基本的原始SQL查询
可以使用FromSql扩展方法,基于原始的SQL查询,开始LINQ查询。
var blogs = context.Blogs
.FromSql("SELECT * FROM dbo.Blogs")
.ToList();
--通过sql server profiler监听的sql,如下所示:
select * from dbo.blogs
1.2 原生 SQL 查询可用于执行存储过程(GetMostPopularBlogs)
var blogs = context.Blogs
.FromSql("EXECUTE dbo.GetMostPopularBlogs")
.ToList();
1.3 传递参数
在使用FromSql执行原始sql查询时,传递参数要防止SQL注入攻击,可以在SQL查询字符串中包含参数占位符,然后提供参数值作为附加参数。任何参数值将自动转换为DbParameter来防止SQL注入。
var id = ;
var blgos= BloggingContext.Blogs.FromSql("select * from dbo.blogs where BlogId={0}",id).ToList();
--通过sql server profiler监听的sql,如下所示:
exec sp_executesql N'select * from dbo.blogs where BlogId=@p0',N'@p0 int',@p0=4
可以构造 DbParameter 并将其作为参数值提供。 这样可以在 SQL 查询字符串中使用命名参数(与上面占位符实现一样,只不过这里显示提供了命名参数@BlogId)。
var user = new SqlParameter("@BlogId", );
var blgos= BloggingContext.Blogs.FromSql("select * from dbo.blogs where BlogId={0}", user).ToList();
--通过sql server profiler监听的sql,如下所示:
exec sp_executesql N'select * from dbo.blogs where BlogId=@BlogId',N'@BlogId int',@BlogId=4
1.4 使用 LINQ 编写
发送到数据库中的 SQL 查询可以是组合的,则可以在原始 SQL 查询后面紧跟着使用 LINQ 运算符。 以 SELECT 关键字开始的 SQL 查询一般是可组合的。以下示例使用原始SQL查询,然后使用LINQ对其进行编写以执行过滤和排序。
var blgos= BloggingContext.Blogs
.FromSql("select blogid,url from dbo.blogs")
.Where(b=>b.BlogId>)
.OrderByDescending(b=>b.BlogId)
.Select(b=> new{ b.BlogId, b.Url})
.ToList();
--通过sql server profiler监听的sql,原始sql成了一个子查询,如下所示:
SELECT [b].[BlogId], [b].[Url]
FROM (
select blogid,url from dbo.blogs
) AS [b]
WHERE [b].[BlogId] > 2
ORDER BY [b].[BlogId] DESC
二. 异步查询
当在数据库中执行查询时,异步查询可避免阻止线程。 这有助于避免冻结富客户端应用程序的 UI。 异步操作还可以增加 Web 应用程序的吞吐量,可以在等数据库操作完成时(I/O),释放当前线程到线程池,该线程可去处理其他请求。
注意: EF Core 不支持在同一上下文实例上运行多个并行操作。 应始终等待操作完成,然后再开始下一个操作。 这通常是通过在每个异步操作上使用 await 关键字完成的。
Entity Framework Core 提供了一组异步扩展方法,可用作执行查询并返回结果的 LINQ 方法的替代方法。示例包括 ToListAsync()、ToArrayAsync()、SingleAsync() 等。对于部分 LINQ 运算符(如 Where(...)、OrderBy(...) 等),没有对应的异步版本,因为这些方法仅用于构建 LINQ 表达式树,而未将查询发送到数据库中执行。
下面是一个示例,注意async必须搭配await,只有await完成后才会释放当前EF上下文, async后面必须是Task(无返回值)或Task<T>(有返回值):
public async Task<List<Blog>> GetBlogsAsync()
{return await context.Blogs.ToListAsync();
}
三. 全局查询筛选器
全局查询筛选器是应用于元数据模型(通常为 OnModelCreating)中的实体类型的 LINQ 查询谓词(通常传递给 LINQ Where 查询运算符的布尔表达式)。
下面使用 HasQueryFilter API 在 OnModelCreating 中配置查询筛选器。
protected override void OnModelCreating(ModelBuilder modelBuilder)
{
//IsDeleted==1 没有被逻辑删除的Blog数据
modelBuilder.Entity<Blog>().HasQueryFilter(b=>b.IsDeleted==);
}
var blgos= BloggingContext.Blogs
.FromSql("select * from dbo.blogs")
.Where(b=>b.BlogId>)
.OrderByDescending(b=>b.BlogId)
.Select(b=> new{ b.BlogId, b.Url})
.ToList();
--通过sql server profiler监听的sql,where后面加了IsDeleted==1,如下所示:
SELECT [b].[BlogId], [b].[Url]
FROM (
select * from dbo.blogs
) AS [b]
WHERE ([b].[IsDeleted] = 1) AND ([b].[BlogId] > 2)
ORDER BY [b].[BlogId] DESC
//可以在Linq查询语句中禁用全局查询筛选器
BloggingContext.Blogs.IgnoreQueryFilters().ToList();
参考文献:
asp.net core系列 33 EF查询数据 (2)的更多相关文章
- asp.net core系列 32 EF查询数据 必备知识(1)
一.查询的工作原理 Entity Framework Core 使用语言集成查询 (LINQ) 来查询数据库中的数据. 通过 LINQ 可使用 C#(或你选择的其他 .NET 语言)基于派生上下文和实 ...
- asp.net core系列 35 EF保存数据(2) -- EF系列结束
一.事务 (1) 事务接着上篇继续讲完.如果使用了多种数据访问技术,来访问关系型数据库,则可能希望在这些不同技术所执行的操作之间共享事务.下面示例显示了如何在同一事务中执行 ADO.NET SqlCl ...
- asp.net core系列 34 EF保存数据(1)
一. 基本数据 每个EF上下文实例都有一个 ChangeTracker(更改跟踪器),它负责跟踪需要写入数据库的更改. 当更改实体类的实例时(修改属性,删除实例,新建实例等),这些更改会记录在 Cha ...
- asp.net core系列 30 EF管理数据库架构--必备知识 迁移
一.管理数据库架构概述 EF Core 提供两种主要方法来保持 EF Core 模型和数据库架构同步.一是以 EF Core 模型为基准,二是以数据库为基准. (1)如果希望以 EF Core 模型为 ...
- asp.net core系列 31 EF管理数据库架构--必备知识 反向工程
一. 反向工程 反向工程是基于数据库架构,生成的实体类和DbContext类代码的过程,对于Visual Studio开发,建议使用PMC.对于其他开发环境,请选择.NET Core CLI工具( ...
- asp.net core 系列 22 EF(连接字符串,连接复原,DbContext)
一.连接字符串 在上二篇中,ASP.NET Core 应用程序连接字符串是写死在ConfigureServices代码中,下面介绍通过配置来实现.连接字符串可以存储在 appsettings.json ...
- asp.net core系列 29 EF模型配置(查询类型,关系数据库建模)
一.查询类型 此功能是EF Core 2.1中的新功能. EF Core除了实体类型之外,EF Core模型还可以包含查询类型,这些查询类型是针对“未映射到实体类型”的数据获取.比如视图,或只读数据表 ...
- asp.net core 系列 21 EF现有数据库进行反向工程
一.概述 在上篇中使用EF基于数据模型创建数据库, 本篇继续使用 EF 基于数据库创建数据模型. 实现对已有数据库进行反向工程,来构建数据访问的 ASP.NET Core MVC 应用程序.已有 ...
- asp.net core 系列 20 EF基于数据模型创建数据库
一.概述 本章使用 Entity Framework Core 构建执行基本数据访问的 ASP.NET Core MVC 应用程序.使用迁移(migrations)基于数据模型创建数据库,是一种cod ...
随机推荐
- json转化技巧
如果用户是一级下拉菜单,二级联动,动态加载内容到二级菜单,并在下方内容处,随着用户选择的内容动态加载相应内容. 实现的方法其实很简单 select部分:一级菜单选择内容,ajax动态加载,因为内容固定 ...
- DCDC设计指南二
DCDC电源设计指导:二 这一讲以一款SOP-8封装的Synchronous Step-Down Converter(同步降压转换器)电源IC为例,讲下电源的PCB设计. 如第一讲中所说,开始设计时就 ...
- 输出九九乘法表(Python、Java、C、C++、JavaScript)
最近在学python的过程中,接触到了循环的知识,以及这个案例,于是写了下!感觉还不错,然后就用其它几种语言也试了下!! 接下来,就跟大家分享下实现方法!! 实现输出九九乘法表,主要用到的是循环的知识 ...
- angularjs和jquery前端发送以http请求formdata数据
formdata是比较常见的前端发送给后端的请求,不仅可以上传数据,而且同时可以上传文件. jquery使用http请求上传formdata数据的方法: var formdata = new Form ...
- linux去除\r(window中编辑的文本)
vim -b file 二进制贷款文件:%s/^M//g # 注意这里使用Ctrl+V+M输入^M 上面的方法我就不行,但是下面的可以: 如果不行可以使用 :%s/\r//
- 201771010126 王燕《面向对象程序设计(Java)》第十三周学习总结
实验十三 图形界面事件处理技术 实验时间 2018-11-22 1.实验目的与要求 (1) 掌握事件处理的基本原理,理解其用途: 事件源 (eventevent eventeventsource s ...
- web 12
调用一个地图(百度地图)API(定位) 到网站: 1.调用API的js : <script type="text/javascript" src="https:// ...
- docker 数据卷管理
在生产环境中使用docker,往往需要对数据进行持久化,或者需要在多个容器之间进行数据共享,这涉及到容器对数据管理的操作 容器对数据的管理主要有两种方式: 数据卷(Data Volumes): 容器内 ...
- 3.1circle
就是括号匹配的题目,如果有交集就是NO #include<iostream> #include<cstring> #include<stdio.h> #includ ...
- c++标准---for循环新用法
贪吃蛇游戏的c++版本,从GitHub上clone下来的,在startinterface.cpp文件中有如下代码: void StartInterface::PrintText() { for ( ...