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;
}
}
}
}