using System.Collections.Generic; using System.Data.Common; using System.Data.SqlClient; using System.Linq; using System.Reflection; using Microsoft.EntityFrameworkCore; using Microsoft.EntityFrameworkCore.Infrastructure; namespace Falcon.ModelSP { /// /// 数据库上下文方法扩展 /// public static class DataExtend { /// /// 执行无返回值的存储过程 /// /// 参数类型 /// 数据上下文 /// 参数数据 public static int RunProcuder(this DbContext db,TPrarmType data) { var parms = getParams(data); return db.Database.ExecuteSqlCommand(getProcuderName(),parms.ToArray()); } /// /// 执行有返回值的存储过程 /// /// 参数类型 /// 返回结果项类型 /// 数据上下文 /// 参数数据 public static IEnumerable RunProcuder(this DbContext db,TPrarmType data) where TResultType : class, new() { var parms = getParams(data); return db.Database.SqlQuery(getProcuderName(),parms.ToArray()).ToList(); } /// /// 获取存储过程参数枚举 /// /// 参数模型类型 /// 参数实例 private static IEnumerable getParams(T data) { if(data == null) yield break; foreach(var p in typeof(T).GetProperties()) { if(!p.CanRead || ignoreProp(p)) continue; yield return new SqlParameter($"@{getName(p)}",p.GetValue(data)); } } /// /// 是否忽略属性 /// /// 要检查的属性 private static bool ignoreProp(PropertyInfo p) { return p.GetCustomAttribute(true) != null; } /// /// 获取存储过程参数名称 /// /// 对应的属性 private static string getName(PropertyInfo p) { var np = p.GetCustomAttribute(true); if(np != null && np is FalconSPPrarmNameAttribute na) { return na.Name; } return p.Name; } /// /// 获取存储过程名 /// /// 参数模型 private static string getProcuderName() { var attr = typeof(T).GetCustomAttribute(true); if(attr != null && attr is FalconSPProcuderNameAttribute pna && !string.IsNullOrEmpty(pna.ProcuderName)) { return pna.ProcuderName; } return typeof(T).Name; } /// /// 根据传入的sql语句和参数枚举执行存储过程,并且返回类型枚举 /// /// 返回值类型 /// 数据库上下文 /// 要执行的sql语句 /// 参数枚举 /// public static IEnumerable SqlQuery(this DatabaseFacade db,string sql,params SqlParameter[] paras) where TR : class, new() { var connection = db.GetDbConnection(); using(var cmd = connection.CreateCommand()) { cmd.CommandText = sql; cmd.CommandType = System.Data.CommandType.StoredProcedure; cmd.Parameters.AddRange(paras); connection.Open(); var dr = cmd.ExecuteReader(); var result = new List(); if(!dr.CanGetColumnSchema()) return result; while(dr.Read()) { var item = new TR(); var columnSchema = dr.GetColumnSchema(); for(var i = 0;i < columnSchema.Count;i++) { var name = dr.GetName(i); var value = dr.IsDBNull(i) ? null : dr.GetValue(i); var pi = typeof(TR).GetProperty(name); if(pi == null || !pi.CanWrite) continue; pi.SetValue(item,value); } result.Add(item); } connection.Close(); return result; } } } }