如何设计公司网站,黄岩区建设规划局网站,企业网站建设杭州公司,上海建设公司注册目录
EFCore执行非查询原生SQL语句
为什么要写原生SQL语句
执行非查询SQL语句
有SQL注入漏洞
ExecuteSqlInterpolatedAsync
其他方法
执行实体相关查询原生SQL语句
FromSqlInterpolated
局限性
执行任意原生SQL查询语句
什么时候用ADO.NET
执行任意SQL
Dapper
总…目录
EFCore执行非查询原生SQL语句
为什么要写原生SQL语句
执行非查询SQL语句
有SQL注入漏洞
ExecuteSqlInterpolatedAsync
其他方法
执行实体相关查询原生SQL语句
FromSqlInterpolated
局限性
执行任意原生SQL查询语句
什么时候用ADO.NET
执行任意SQL
Dapper
总结 EFCore执行非查询原生SQL语句
为什么要写原生SQL语句
尽管EF Core已经非常强大但是仍然存在着无法被写成标准EF Core调用方法的SQL语句少数情况下仍然需要写原生SQL。可能无法跨数据库。三种情况非查询语句、实体查询、任意SQL查询。
执行非查询SQL语句
使用dbCtx.Database. ExecuteSqlInterpolated ()
dbCtx.Database. ExecuteSqlInterpolatedAsync()方法来执行原生的非查询SQL语句。
static async Task Main(string[] args)
{using (MyDbContext ctx new MyDbContext()){string strName 小刘;await ctx.Database.ExecuteSqlInterpolatedAsync($insert into T_Books(Name,Author,Price)select Name,{strName},Pricefrom T_Books where Price 20);}
}
有SQL注入漏洞
字符串内插的方式会不会有SQL注入攻击漏洞吗查看一下执行的SQL语句吧。
insert into T_Books(Name,Author,Price)
select Name,p0,Price
from T_Books where Price 20
ExecuteSqlInterpolatedAsync
字符串内插如果赋值给string变量就是字符串拼接字符串内插如果赋值给FormattableString变量编译器就会构造FormattableString 对象。打印FormattableString的成员试试看。
static async Task Main(string[] args)
{using (MyDbContext ctx new MyDbContext()){string strName 小刘;FormattableString sql ($insert into T_Books(Name,Author,Price)select Name,{strName},Pricefrom T_Books where Price 20);Console.WriteLine(Format: sql.Format);Console.WriteLine(参数 string.Join(,, sql.GetArguments()));}
} ExecuteSqlInterpolatedAsync()的参数是FormattableString类型。因此ExecuteSqlInterpolatedAsync会进行参数化SQL的处理。
其他方法
除了ExecuteSqlInterpolated ()、ExecuteSqlInterpolatedAsync() 还有ExecuteSqlRaw()、ExecuteSqlRawAsync() 也可以执行原生SQL语句但需要开发人员自己处理查询参数因此不推荐使用。
执行实体相关查询原生SQL语句
FromSqlInterpolated
如果要执行的原生SQL是一个查询语句并且查询的结果也能对应一个实体就可以调用对应实体的DbSet的FromSqlInterpolated()方法来执行一个查询SQL语句同样使用字符串内插来传递参数。
static async Task Main(string[] args)
{using (MyDbContext ctx new MyDbContext()){string NamePattern %计算%;var queryable ctx.Books.FromSqlInterpolated($select * from T_Books where Name Like {NamePattern} order by newid());foreach (var item in queryable){Console.WriteLine(item.Id item.Name);}}
}
select * from T_Books where Name Like p0 order by newid()
FromSqlInterpolated()方法的返回值是IQueryable类型的因此我们可以在实际执行IQueryable之前对IQueryable进行进一步的处理。
把只能用原生SQL语句写的逻辑用FromSqlInterpolated()去执行然后把分页、分组、二次过滤、排序、Include等其他逻辑尽可能仍然使用EF Core的标准操作去实现。
局限性
SQL 查询必须返回实体类型对应数据库表的所有列结果集中的列名必须与属性映射到的列名称匹配。只能单表查询不能使用Join语句进行关联查询。但是可以在查询后面使用Include()来进行关联数据的获取。
执行任意原生SQL查询语句
什么时候用ADO.NET
FromSqlInterpolated()只能单表查询但是在实现报表查询等的时候SQL语句通常是非常复杂的不仅要多表Join而且返回的查询结果一般也都不会和一个实体类完整对应。因此需要一种执行任意SQL查询语句的机制。
EF Core中允许把视图或存储过程映射为实体因此可以把复杂的查询语句写成视图或存储过程然后再声明对应的实体类并且在DbContext中配置对应的DbSet。
不推荐写存储过程项目复杂查询很多导致视图太多非实体的DbSetDbSet膨胀。
执行任意SQL
dbCxt.Database.GetDbConnection()获得ADO.NET Core的数据库连接对象。
Dapper
推荐用Dapper等框架执行原生复杂查询SQL。
EF Core和Dapper并不是对立可以同时使用EF Core简单方便
var items ctx.Database.GetDbConnection().QueryGroupArticleByPrice(select Price,Count(*) PCount from T_Books group by price);
foreach (var item in items)
{Console.WriteLine($Price{item.Price},Count{item.PCount});
}
总结
一般Linq操作就够了尽量不用写原生SQL
非查询SQL用ExecuteSqlInterpolated () 针对实体的SQL查询用FromSqlInterpolated()。复杂SQL查询用ADO.NET的方式或者Dapper等。