asp.net core系列 33 EF查询数据 (2)

时间:2019-08-28 09:59 作者:Mr.Pan 阅读数:550


一. 原生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 = 4;
       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", 4);
       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>2)
                .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==1);
        }

复制代码

         var blgos=  BloggingContext.Blogs
                .FromSql("select * from dbo.blogs")
                .Where(b=>b.BlogId>2)
                .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 查询

  异步查询

  全局查询筛选器



文章转自:https://www.cnblogs.com/MrHSR/p/10444143.html


推荐文章

[推荐] .NET Core 学习资料精选:入门

[推荐] 数据库常见死锁原因及处理

[推荐] C# 设置Excel数据自适应行高、列宽的2种情况 (转)

[推荐] C++ vector 和set结合数字去重练习

[推荐] win7 .net core 部署 The library hostfxr.dll was found, but loading it from C:\<path_to_app>\hostfxr.dll failed

[推荐] JdbcTemplate多数据源使用

[推荐] 深入学习Redis(2):持久化

[推荐] asp.net core系列 67 Web压力测试工具WCAT

[推荐] .Net Core 2.0 获取客户端IP地址

[推荐] 第七天 让你的container实现跨主机访问

[推荐] 8天玩转并行开发——第八天 用VS性能向导解剖你的程序

[推荐] nodejs app.use(express.static) 静态文件托管 (四)

[推荐] C++ 稀疏表的练习

[推荐] asp.net core系列 33 EF查询数据 (2)

[推荐] C++ Lambda表达式练习

[推荐] Spring Boot 2 (五):Docker Compose + Spring Boot + Nginx + Mysql 实践

[推荐] 试试发布

[推荐] C++中 *p++ 到底是 *(p++) 还是 (*p)++ 1. 猜想

[推荐] JavaWeb-Log4j: WARN No appenders could be found for logger

[推荐] C++ 模板练习


评论列表



注册用户登录后才能发表评论,请登录注册,访问 博客首页