EF Core调用Mysql中的存储过程,驱动为Pomelo.EntityFrameworkCore.MySql。
methodname
2018年12月5日• 2 min read
EF Core在mysql中调用存储过程,博主找了很多,然而大多都是EF Core+SqlServer的或者EF Core+Oracle的,并没有正对Mysql的Pomelo驱动的,所以查找了一些资料和博文之后,进行一些修改,最终得到下面的代码。
1. 方式一【FromSql】
搜索到的基本上都这样的方式
using (var dataContext = new DbContext()) { var param = 1; var query = dataContext.Table.FromSql($"procname {param}"); var result = query.ToList(); Assert.NotNull(result); }
然而这种方式有两个弊端,一是Table必须是包含在DbContext中,这也就意味着要建一个对应的表在数据库中,二是这种查询在mysql的pomelo驱动中,会存在一些不完善,导致在数据库直接执行存储过程的结果和在EF Core中调用执行的结果不一致,且还会出现数据集结果全是一样的重复数据,所以这种方式在EF Core+Mysql中不能使用。
2. 方式二【ExecuteReader】
使用最基本的读取方式,这种方式基本上已经脱离了EF上下文,具体可以参考链接EF切EFCore2.0存储过程问题
不过博主的这篇文章是针对sqlserver的,mysql并不使用,所以我改写了一下使用ExecuteReader读取数据的过程,添加一个方法在DbContext类中,代码如下
///添加到EF上下文DbContext.cs中/// /// 执行sql查询/// /// 结果集类型/// 执行语句/// 参数/// public IEnumerable SqlQuery(string sql, params object[] parameters) where TElement : new(){ using (var content = new ETLDbContextFactory().CreateDbContext()) { var connection = Database.GetDbConnection(); using (var cmd = connection.CreateCommand()) { Database.OpenConnection(); cmd.CommandText = sql; cmd.CommandType = System.Data.CommandType.StoredProcedure; cmd.Parameters.AddRange(parameters); var dr = cmd.ExecuteReader(); var data = new List(); ; while (dr.Read()) { TElement item = new TElement(); Type type = item.GetType(); foreach (var propertyInfo in type.GetProperties()) { //var propertyInfo = type.GetProperty(kv.Name); //if (kv.GetConstantValue.HasValue && propertyInfo != null) //{ //注意需要转换数据库中的DBNull类型 var value = dr.GetValue(dr.GetOrdinal(propertyInfo.Name)); propertyInfo.SetValue(item, value); //} } data.Add(item); } dr.Dispose(); return data; } }}
调用
using (var content = new DbContext()){ //这个地方的调用存储过程,只需要传入存储过程名字,不用像mysql中还需要在前面加call,参数于存储过程的参数对应放在MySqlParameter数组中即可 var result = content.SqlQuery("get_tablelist_with_dbname", new MySql.Data.MySqlClient.MySqlParameter("dbname", "bfstock")); return result.ToList();}
原创文章,作者:筱凯,如若转载,请注明出处:https://www.jingyueyun.com/ask/358.html