EF Coer 原生sql查询

    1. EF Core提供的执行SQL语句的方法
    2. 自己封装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)

 

posted @ 2019-10-28 14:22  小小豆豆  阅读(1309)  评论(0编辑  收藏  举报