EF Core 执行原生SQL
1. 执行Sql 非查询语句
[HttpPost("InsertBatch")] public async Task<ActionResult> InsertBatch() { string title = "执行原生Sql非查询语句"; double price = 89.6; DateTime date = DateTime.Now; int rows = await _context.Database .ExecuteSqlInterpolatedAsync($@"insert into T_Book (Title,PUbTime,Price,AuthorName) values({title},{date},{price},'张三')"); return Ok(rows); }
ExecuteSqlInterpolatedAsync() 方法会将插入字符串中的插入值{tile}转换成参数形式的Sql,所以不用担心Sql注入问题。(推荐)
ExecuteSqlRawAsync() 是拼溱字符串,会有Sql注入风险。
2. 执行实体类Sql查询语句
由于IQueryable这种线 大的“查询再加工”能力,我们可以把只能用原生Sql语句写的逻辑用FromSqlInterpolated执行,然后把分页、分组、二次过滤、排序、Include等其他逻辑仍然使用EF Core 的标准操作实现。
FromSqlInterpolated的使用有以下局限性:
- 查询结果集必须和实体类一 一对应。
- 必须返回表的全部列。
- 只能进行单表查询,不能使用Join关联查询,但在查询后可再使用Include方法进行关联数据的获取。
[HttpPost("QueryModel")] public async Task<ActionResult> QueryModel() { int year = 2018; //非标准查询用FromSqlInterpolated执行 IQueryable<Book> books = _context.Books .FromSqlInterpolated($@"select * from T_Book where Datepart(year,pubtime)>{year}"); //再用标准查询进行二次加工 var list=books.Skip(2).Take(6); return Ok(list); }
3. 执行任意Sql查询语句
FromSqlInterpolated 只能执行单个实体类的查询,但是在实现报表查询时,Sql语句通常是非常复杂,不仅要关联多个表,而且返回的结果也一般没有对应的实体类。
3.1 EF Core 中允许把视图或存储过程映射为实体类,因此我们可以把复杂的查询写成视图或者存储过程,然后声明对应的实体类,并且在上下文中配置对应的DbSet属性。
推荐创建视图,而非存储过程。
3.2 使用Dapper轻量级的ORM工具
通过dbContext.Database.GetDbConnection 获取数据库连接