EF Coer 原生sql查询
- EF Core提供的执行SQL语句的方法
- 自己封装SqlQuery方法,执行SQL语句
一.EF Core提供的执行SQL语句的方法
基于原始SQL查询创建LINQ查询,
FromSql
方法的返回类型只有IQueryable<T>
。
SqlParameter parameter = new SqlParameter("Id", 1);
User user = context.Set<User>("select * from User where Id=@Id", parameter).Single();
对数据库执行给定的SQL并返回受影响的行数。需要引用
Microsoft.EntityFrameworkCore
命名空间。
SqlParameter[] parameters = new []{
new SqlParameter("Id", 1),
new SqlParameter("Name", "zhansan")
};
context.Database.ExecuteSqlCommand("update User set Name=@Name where Id=@Id", parameters);
二.自己封装SqlQuery方法,执行SQL语句
但在EF Core提供的的执行SQL语句的方法发现许多问题,比如:
- 不支持返回特定的泛型类型的元素
- 执行SQL查询语句查询某张表时查询返回的字段必须是该表的所有字段
所以根据上述问题,需要自己封装执行Sql语句查询的方法。
/// <summary> /// 执行mysql原生语句 /// </summary> /// <typeparam name="TEntity">查询返回结果的Dto</typeparam> /// <param name="mysql">MySQL语句</param> /// <param name="timeOutNum">超时时间</param> /// <param name="parameters">MySQLParameter 参数防止sql注入</param> /// <returns>返回结果Dto的集合</returns> public IList<TEntity> SqlQuery<TEntity>(string mysql, int? timeOutNum = null, params object[] parameters) where TEntity : new() { //注意:不要对GetDbConnection获取到的conn进行using或者调用Dispose,否则DbContext后续不能再进行使用了,会抛异常 var conn = db.Database.GetDbConnection(); try { conn.Open(); using (var command = conn.CreateCommand()) { if (timeOutNum.HasValue) { command.CommandTimeout = timeOutNum.Value; } command.CommandText = mysql; if (parameters.Count() > 0) { command.Parameters.AddRange(parameters); } var propts = typeof(TEntity).GetProperties(); var rtnList = new List<TEntity>(); TEntity model; object val; using (var reader = command.ExecuteReader()) { while (reader.Read()) { model = new TEntity(); foreach (var l in propts) { val = reader[l.Name]; if (val == DBNull.Value) { l.SetValue(model, null); } else { l.SetValue(model, val); } } rtnList.Add(model); } } return rtnList; } } finally { conn.Close(); } }
使用:
//参数 MySqlParameter nameParameter = new MySqlParameter("name", "zhangsan"); //整理MySQLParameter集合, var hash = new HashSet<MySqlParameter>(); hash.Add(nameParameter); var count = hash.Count(); //SqlQuery()方法传入的MySQLParameter数组,给其赋值 MySqlParameter[] mySqlParameter = new MySqlParameter[count + 1]; foreach (var item in hash) { mySqlParameter[i] = item; } var list = SqlQuery<Model>(mysql: mysql, parameters: mySqlParameter)