asp.net core 2.1 dotnet(五)EF.core Dbfirst 生成 檢視與呼叫儲存過程
1 檢視,可以直接在 Model中寫 檢視的模型 執行方式如找到一個,還沒有試過:
有關 .net core EF 的問題有一個地址:
https://github.com/aspnet/EntityFrameworkCore/issues/4561
2.儲存過程:
使用EF Core框架能快速的幫助我們進行常規的資料處理和專案開發,但是ORM雖然好用,但是在許多複雜邏輯的資料處理時,我個人還是偏向用SQL和儲存過程的方式去處理,但是研究了一下目前最新版本的EF Core(我用的是2.1)以及相關文件,貌似沒有找到可以很好支援原始SQL開發的方案,於是就自己簡單的擴充套件了一下
首先說一下我查閱文件找到已知的EF Core可以執行SQL和儲存過程的兩個函式ExecuteSqlCommand()和FromSql()
1,ExecuteSqlCommand(),程式碼中的EntityContext即為資料框架上下文物件,這種方法可以執行sql或者儲存過程並且傳遞引數,但是缺點就是函式的返回結果為int型別的受影響行數,無法返回指定的資料集
private EntityContext context = null; public ValuesController(EntityContext _context) { context = _context; } /// <summary> /// 測試程式碼 /// </summary> /// <returns></returns> [HttpPost("Post")] public int Post() { long uid = 4; int data = context.Database.ExecuteSqlCommand($"exec proc_test {uid}", uid); return data; }
2,FromSql()可以用來執行帶引數的sql,這個函式的用法以及優缺點可以看官方文件的這篇文章
https://docs.microsoft.com/en-us/ef/core/querying/raw-sql
3,用DbCommand 簡單的擴充套件資料框架上下文物件,使其可以執行儲存過程並返回你想要的資料型別
public static class ExtendDBContext { /// <summary> /// 執行SQL返回受影響的行數 /// </summary> public static int ExecSqlNoQuery<T>(this EntityContext db, string sql, SqlParameter[] sqlParams = null) where T : new() { return ExecuteNoQuery<T>(db, sql, sqlParams); } /// <summary> /// 執行儲存過程返回IEnumerable資料集 /// </summary> public static IEnumerable<T> ExecProcReader<T>(this EntityContext db, string sql, SqlParameter[] sqlParams = null) where T : new() { return Execute<T>(db, sql, CommandType.StoredProcedure, sqlParams); } /// <summary> /// 執行sql返回IEnumerable資料集 /// </summary> public static IEnumerable<T> ExecSqlReader<T>(this EntityContext db, string sql, SqlParameter[] sqlParams = null) where T : new() { return Execute<T>(db, sql, CommandType.Text, sqlParams); } private static int ExecuteNoQuery<T>(this EntityContext db, string sql, SqlParameter[] sqlParams) where T : new() { DbConnection connection = db.Database.GetDbConnection(); DbCommand cmd = connection.CreateCommand(); int result = 0; db.Database.OpenConnection(); cmd.CommandText = sql; cmd.CommandType = CommandType.Text; if (sqlParams != null) { cmd.Parameters.AddRange(sqlParams); } result = cmd.ExecuteNonQuery(); db.Database.CloseConnection(); return result; } private static IEnumerable<T> Execute<T>(this EntityContext db, string sql, CommandType type, SqlParameter[] sqlParams) where T : new() { DbConnection connection = db.Database.GetDbConnection(); DbCommand cmd = connection.CreateCommand(); db.Database.OpenConnection(); cmd.CommandText = sql; cmd.CommandType = type; if (sqlParams != null) { cmd.Parameters.AddRange(sqlParams); } DataTable dt = new DataTable(); using (DbDataReader reader = cmd.ExecuteReader()) { dt.Load(reader); } db.Database.CloseConnection(); return dt.ToCollection<T>(); } }
DataTable和集合的擴充套件
public static class ExtendDataTable { public static DataTable ToDataTable<T>(this IEnumerable<T> data) { PropertyDescriptorCollection properties = TypeDescriptor.GetProperties(typeof(T)); var table = new DataTable(); foreach (PropertyDescriptor prop in properties) table.Columns.Add(prop.Name, Nullable.GetUnderlyingType(prop.PropertyType) ?? prop.PropertyType); foreach (T item in data) { DataRow row = table.NewRow(); foreach (PropertyDescriptor prop in properties) row[prop.Name] = prop.GetValue(item) ?? DBNull.Value; table.Rows.Add(row); } return table; } public static T ToEntity<T>(this DataTable dt) where T : new() { IEnumerable<T> entities = dt.ToCollection<T>(); return entities.FirstOrDefault(); } public static IEnumerable<T> ToCollection<T>(this DataTable dt) where T : new() { if (dt == null || dt.Rows.Count == 0) { return Enumerable.Empty<T>(); } IList<T> ts = new List<T>(); // 獲得此模型的型別 Type type = typeof(T); string tempName = string.Empty; foreach (DataRow dr in dt.Rows) { T t = new T(); PropertyInfo[] propertys = t.GetType().GetProperties(); foreach (PropertyInfo pi in propertys) { tempName = pi.Name; //檢查DataTable是否包含此列(列名==物件的屬性名) if (dt.Columns.Contains(tempName)) { // 判斷此屬性是否有Setter if (!pi.CanWrite) continue;//該屬性不可寫,直接跳出 object value = dr[tempName]; if (value != DBNull.Value) pi.SetValue(t, value, null); } } ts.Add(t); } return ts; } }
說明:上面的程式碼是通過datareader的方式獲取資料集的,當然DbCommand 也支援非同步的方式處理資料,我這邊沒有用到所以程式碼也就沒有做擴充套件,我貌似沒有找到可以通過dataadapter來填充dataset的方式獲取資料集的相關函式,如果有小夥伴知道在如何在EF Core中用dataadapter來填充dataset的方式獲取資料集,可以把程式碼貼評論區哦
付傷年華的技術分享