.net core EF Core调用存储过程的方式

前言

在这里,我们将尝试去学习一下 .net core EF Core 中调用存储过程。

我们知道,EF Core 是不支持直接调用存储过程的,那它又提供了什么样的方式去执行存储过程呢?有如下方法:

1、FromSql,官方文档

DbSet<TEntity>.FromSql()

2、执行SQl命令

DbContext.Database.ExecuteSqlCommand()

但是,这两种方式都有局限性:

1、FromSql方式的结果一定要是实体类型,就是数据库表映射的模型。这意味着,执行存储过程返回的结果一定是跟数据库表相关的所有字段;

2、FromSql方式的结果不能有关联关系数据。这就相当于不能 join ,也返回不了 join 的关联表的数据。

3、ExecuteSqlCommand执行插入、更新跟删除的存储过程不能直接映射到实体(EF Core不支持嘛,在讲 EF 跟 EF Core 的区别时已经很清晰了),所以,CUD 方法不能直接调用 SaveChanges 方法。

我们来试试演示一下:

(1)准备一个存储过程,一般为了方便,直接就是 DB-First,执行以下的 SQL 脚本就OK了

USE [Library]
GO

SET ANSI_NULLS ON
GO

SET QUOTED_IDENTIFIER ON
GO

CREATE PROCEDURE [dbo].[proc_getbooks]
   @name nvarchar(50)
  AS
  BEGIN
   SET NOCOUNT ON;
   select * from books where name like @name +'%'
  END
GO

当创建好了这个有传参的有返回结果的存储过程的时候,数据库在可编程性下就有一个存储过程了(这个数据库是我专门用来做demo的)

(2)用 FromSql 调用存储过程,由上面就可以知道它是 DbSet 的方法,而 DbSet 是可以执行原生的 sql 语句去查询底层的数据库。同样,使用 DbSet 可以执行存储过程,从而返回实体类型,但就是具有上面所说的局限性罢了。

//用 FromSql 调存储过程
   var name = "C";

   var books = _context.Books
      .FromSql($"proc_getbooks {name}")
      .ToList();

   //or 使用 exec 关键字调用存储过程
   //var books = _context.Books.FromSql($"exec proc_getbooks {name}").ToList();

   //or 使用 SqlParameter 实例进行参数的插入
   //var param = new SqlParameter()
   //{
   // ParameterName = "@name",
   // SqlDbType = System.Data.SqlDbType.NVarChar,
   // Direction = System.Data.ParameterDirection.Input,
   // Size = 50,
   // Value = name
   //};

   //or 使用 @p0 代表第一个参数,则 @p1 就代表第二个参数等以此类推
   //var books = _context.Books.FromSql("proc_getbooks @p0", name).ToList();

同样,在这里值得一提的是,当我们多次调用同一个存储过程,传递同样的参数的时候,比如像下面:

//用 FromSql 多次调同一个存储过程
   var name = "C";

   var list1 = _context.Books.FromSql($"proc_getbooks {name}").ToList();

   var list2 = _context.Books.FromSql($"proc_getbooks {name}").ToList();

   var list3 = _context.Books.FromSql($"proc_getbooks {name}").ToList();

所有的实体默认(可以设置)都会被 DbContext 进行跟踪。如果你执行同样的存储过程,传同样的参数的时候,进行多次执行的时候,相当于执行同样的 sql 语句多次,但返回的结果确认一样的, 根据DbContext 的跟踪,直接就获取缓存进行返回结果了。就是说,存储过程会被调用多次,但只查了一次数据库,其他的在缓存里拿数据。

(3)用ExecuteSqlCommand 调用存储过程,这个跟 EF 是一个毛样的,由于要测试的话,还要创建一个存储过程,因为这个执行查询没有意义,如果你看它的返回的话,都是 int 类型,而且返回结果都是影响的行数。

看看源码:

其实 ExecuteSqlCommand 最终是调用 ExecuteNonQuery,就是执行非查询的语句,返回影响的行数,也验证了刚才所说的。

扯远了,那么再创建一个存储过程吧

CREATE PROCEDURE [dbo].[proc_createbook]
 @name Varchar(50),
 @author Varchar(50),
 @cateid int
AS
BEGIN
 SET NOCOUNT ON;
 Insert into books(
   [name]
   ,[author]
   ,[createtime]
   ,[isdel]
   ,[cateid]
   )
 Values (@name, @author,GETDATE(),0,@cateid)
END
GO

创建后

来调用以下试试:

   //用 ExecuteSqlCommand 调存储过程, 用parameters: new[] {}也是可以的
   var name = "C# 高级进阶";
   var author = "-";
   var cateid = 1;
   _context.Database.ExecuteSqlCommand("proc_createbook @p0,@p1,@p2", name, author, cateid);

执行结果:

OK,是可以执行成功的。

到这里先完成第一部分先,接下来就做调用存储过程的扩展,因为单靠这两种调用方式,我们是不会满足的!

总结

以上就是这篇文章的全部内容了,希望本文的内容对大家的学习或者工作具有一定的参考学习价值,谢谢大家对我们的支持。

(0)

相关推荐

  • .net core EF Core调用存储过程的方式

    前言 在这里,我们将尝试去学习一下 .net core EF Core 中调用存储过程. 我们知道,EF Core 是不支持直接调用存储过程的,那它又提供了什么样的方式去执行存储过程呢?有如下方法: 1.FromSql,官方文档 DbSet<TEntity>.FromSql() 2.执行SQl命令 DbContext.Database.ExecuteSqlCommand() 但是,这两种方式都有局限性: 1.FromSql方式的结果一定要是实体类型,就是数据库表映射的模型.这意味着,执行存储过

  • C#开发Winform程序调用存储过程

    数据表及数据准备: create table Member ( MemberId int primary key identity(1,1), MemberAccount nvarchar(20) unique, MemberPwd nvarchar(20), MemberName nvarchar(20), MemberPhone nvarchar(20) ) truncate table Member insert into Member(MemberAccount,MemberPwd,Me

  • 在.NET Core类库中使用EF Core迁移数据库到SQL Server的方法

    前言 如果大家刚使用EntityFramework Core作为ORM框架的话,想必都会遇到数据库迁移的一些问题. 起初我是在ASP.NET Core的Web项目中进行的,但后来发现放在此处并不是很合理,一些关于数据库的迁移,比如新增表,字段,修改字段类型等等,不应该和最上层的Web项目所关联,数据的迁移文件放到这里也感觉有点多余,有点乱乱的感觉,所以才想着单独出来由专门的项目进行管理会比较好,也比较清晰! 注意目标框架选择的是.NET Core 2.0而不是.NET Standard 2.0.

  • .net core实用技巧——将EF Core生成的SQL语句显示在控制台中

    前言 笔者最近在开发和维护一个.NET Core项目,其中使用几个非常有意思的.NET Core相关的扩展,在此总结整理一下. EF Core性能调优 如果你的项目中使用了EF Core, 且正在处于性能调优阶段,那么了解EF Core生成的SQL语句是非常关键的.那么除了使用第三方工具,如何查看EF Core生成的SQL语句呢?这里笔者将给出一个基于.NET Core内置日志组件的实现方式. 创建一个实例项目 我们首先建一个控制台程序,在主程序中我们编写了一个最简单的EF查询. class P

  • .net EF Core专题:EF Core 读取数据时发生了什么?

    原文:https://bit.ly/2UMiDLb 作者:Jon P Smith 翻译:王亮 声明:我翻译技术文章不是逐句翻译的,而是根据我自己的理解来表述的.其中可能会去除一些本人实在不知道如何组织但又不影响理解的句子. 本文将为你详细描绘 EF Core 从数据库中读取数据的"幕后"视图.我将揭开两种数据库读取方式的面纱:一个是普通的查询,另一个是使用 AsNoTracking 方法的非跟踪查询.我还将通过一个实验来演示我是如何解决我的一个客户遇到的性能问题. 我假设你对 EF C

  • EF Core通过显式编译提高查询性能

    今天,我将向您展示这些EF Core中一个很酷的功能,通过使用显式编译的查询,提高查询性能. 不过在介绍具体内容之前,需要说明一点,EF Core已经对表达式的编译使用了缓存:当您的代码需要重用以前执行的查询时,EF Core将使用哈希查找并从缓存中返回已编译的查询. 不过,您可能希望直接对查询进行编译,跳过哈希的计算和缓存查找.我们可以通过在EF静态类中下面两个方法来实现: EF.CompileQuery() EF.CompileAsyncQuery() 这些方法允许您定义一个已编译的查询,然

  • EF Core基础入门教程

    EF Core 是一个ORM(对象关系映射),它使 .NET 开发人员可以使用 .NET对象操作数据库,避免了像ADO.NET访问数据库的代码,开发者只需要编写对象即可. EF Core 支持多种数据库引擎: Microsoft SQL Sever SQLite Npgsql MySQL ...... 1.获取EF Core 通过NuGet获取要使用的数据库支持.比如:Microsoft SQL Sever 打开NuGet程序包管理器控制台,输入:Install-PackageMicrosoft

  • EF Core的CRUD(增删改查)基本操作

    一.增加(C) 单笔增加 //添加 static void Add() { using (var db = new Entities()) { Student stu1 = new Student { Name = "李四", Age = 19, Adress = "合肥", PhoneNumber = "13200000000" }; //把实体对象附加到上下文 db.Student.Add(stu1); //db.Entry(stu1).St

  • Springmvc调用存储过程,并返回存储过程返还的数据方式

    目录 Springmvc调用存储过程,并返回存储过程返还的数据 实现如下 这里要重点说明一下 Springmvc调用存储过程,entity文件写法 Springmvc调用存储过程,并返回存储过程返还的数据 java后端很多时候都需要和数据库进行交互,并返回业务数据.一般情况下都会采用执行SQL的方式来进行交互,但有些特别的场景时,也可以直接利用存储过程返回数据. 存储过程返回数据的好处是只需要一个调用,即可根据不同的参数返回不同的业务数据,这些业务数据有可能列名完全不一样. 实现如下 首先要先定

  • C# EF Core可视化工具的使用及EF Core入门语句操作代码

    目录 前言 一.EFCoreTools的下载 二.EFCoreTools的使用 1.新建项目并引入EFCoreTools 2.手动引入EFCore的包 三.EFCore的填查删改 1.添加操作 2.查找操作 3.删除操作 4.修改操作 四.总结 前言 Entity Framework (EF) Core 是轻量化.可扩展.开源和跨平台版的常用 Entity Framework 数据访问技术. 一.EF Core Tools的下载 EFCore Tools可视化工具下载后安装,并重启ViusalS

随机推荐