- 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)