一. 原生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();

参考文献:

  原生 SQL 查询

  异步查询

  全局查询筛选器

asp.net core系列 33 EF查询数据 (2)的更多相关文章

  1. asp.net core系列 32 EF查询数据 必备知识(1)

    一.查询的工作原理 Entity Framework Core 使用语言集成查询 (LINQ) 来查询数据库中的数据. 通过 LINQ 可使用 C#(或你选择的其他 .NET 语言)基于派生上下文和实 ...

  2. asp.net core系列 35 EF保存数据(2) -- EF系列结束

    一.事务 (1) 事务接着上篇继续讲完.如果使用了多种数据访问技术,来访问关系型数据库,则可能希望在这些不同技术所执行的操作之间共享事务.下面示例显示了如何在同一事务中执行 ADO.NET SqlCl ...

  3. asp.net core系列 34 EF保存数据(1)

    一. 基本数据 每个EF上下文实例都有一个 ChangeTracker(更改跟踪器),它负责跟踪需要写入数据库的更改. 当更改实体类的实例时(修改属性,删除实例,新建实例等),这些更改会记录在 Cha ...

  4. asp.net core系列 30 EF管理数据库架构--必备知识 迁移

    一.管理数据库架构概述 EF Core 提供两种主要方法来保持 EF Core 模型和数据库架构同步.一是以 EF Core 模型为基准,二是以数据库为基准. (1)如果希望以 EF Core 模型为 ...

  5. asp.net core系列 31 EF管理数据库架构--必备知识 反向工程

    一.   反向工程 反向工程是基于数据库架构,生成的实体类和DbContext类代码的过程,对于Visual Studio开发,建议使用PMC.对于其他开发环境,请选择.NET Core CLI工具( ...

  6. asp.net core 系列 22 EF(连接字符串,连接复原,DbContext)

    一.连接字符串 在上二篇中,ASP.NET Core 应用程序连接字符串是写死在ConfigureServices代码中,下面介绍通过配置来实现.连接字符串可以存储在 appsettings.json ...

  7. asp.net core系列 29 EF模型配置(查询类型,关系数据库建模)

    一.查询类型 此功能是EF Core 2.1中的新功能. EF Core除了实体类型之外,EF Core模型还可以包含查询类型,这些查询类型是针对“未映射到实体类型”的数据获取.比如视图,或只读数据表 ...

  8. asp.net core 系列 21 EF现有数据库进行反向工程

    一.概述 在上篇中使用EF基于数据模型创建数据库,  本篇继续使用 EF  基于数据库创建数据模型.  实现对已有数据库进行反向工程,来构建数据访问的 ASP.NET Core MVC 应用程序.已有 ...

  9. asp.net core 系列 20 EF基于数据模型创建数据库

    一.概述 本章使用 Entity Framework Core 构建执行基本数据访问的 ASP.NET Core MVC 应用程序.使用迁移(migrations)基于数据模型创建数据库,是一种cod ...

随机推荐

  1. 2019-3-26WinForm窗体间如何传值的几种方法

    窗体间传递数据,无论是父窗体操作子窗体,还是子窗体操作符窗体,有以下几种方式: 公共静态变量: 使用共有属性: 使用委托与事件: 通过构造函数把主窗体传递到从窗体中: 一.通过静态变量 特点:传值是双 ...

  2. Y1吐槽002 情绪

    看了石原里美的<高岭之花>,虽然全程基本都是看不懂的,但是风间直人对喜怒哀乐里面的怒和哀的分析还是深有感触. 悲哀的人心里有爱 愤怒的人心里有恨,一个人装了太多的恨的话,别人是拯救不了的: ...

  3. 我的 FPGA 学习历程(12)—— 电子钟项目准备

    初学 FPGA 的时候,我们总是存在很多疑问,比如:xilinx 和 altera 的 FPGA 那种比较好.verilog 语言被如何综合成具体硬件电路.RTL 级电路是什么意思等等.现在我们就不会 ...

  4. Python3-大魔王小项目-田忌赛马

    本人今天第一次接触项目,花了4小时,不包括学习时间,特此留个纪念 记录一下那些年走过的坑,以资鼓励 英语不怎么好,随缘看看 内容: 类似田忌赛马,三盘两胜,属性人物在一定范围内随机,就这样了 code ...

  5. 微信跳转,手机WAP浏览器一键超级跳转微信指定页面

    微信跳转,手机WAP浏览器一键超级跳转微信指定页面 这篇文章主要介绍了如何在手机浏览器wap网页中点击链接跳转到微信界面,需要的朋友可以参考下 先说第一种,最简单的唤起微信协议,weixin://主流 ...

  6. console.log

    其实,console.log 不仅仅有一下应用 console.log() 这个应该是最常用的 console.error() 输出错误信息 会以红色显示 console.assert(bool,”i ...

  7. Markdown基础语法笔记

    # 一级标题## 二级标题### 三级标题###### #号之后记得加一个空格 仅支持1-6级标题  ### 列表 - 文本1 - 文本2 - 文本3+ 列表2* 列表2 ### 有序列表1. 有序文 ...

  8. [Codeforces Round #516][Codeforces 1063B/1064D. Labyrinth]

    题目链接:1063B - Labyrinth/1064D - Labyrinth 题目大意:给定一个\(n\times m\)的图,有若干个点不能走,上下走无限制,向左和向右走的次数分别被限制为\(x ...

  9. python爬虫第四天

        昨天学到了正则表达式基础知识 :原子 今天开始学习第二个基础知识:元字符 元字符     就是正则表达式中含有特殊含义的一些字符 常见的元字符及含义   符号 含义 . 匹配除换行符以外 的任 ...

  10. JAVA---MYSQL 基本知识点 第二部分

    增删改查 (CRUD):   数据库  , 表  , 记录  ;   约束 ; 主键约束 :primary key  如果是int类型 可以使用 自动增长型  auto_increment; 唯一约束 ...