可以通过FalconSPReturnTypeAttribute特性在存储过程参数模型中定义返回结果模型

This commit is contained in:
falcon 2020-11-20 14:59:21 +08:00
parent bad9973d3c
commit 5943fc6247
7 changed files with 156 additions and 14 deletions

View File

@ -49,13 +49,13 @@ namespace Falcon.ModelSP.Test
public void InMemoryDbTest() {
//内存数据库无法使用关系模型,测试无法进行
return;
using(var db = TestDbContext.GetDbInMemory()) {
var re = db.Pr_AddOne(new Pr_AddOne { A = 1 });
Assert.IsTrue(re != null);
Assert.IsTrue(re.Any());
var first = re.First();
Assert.IsTrue(first.Aa == 2);
}
//using(var db = TestDbContext.GetDbInMemory()) {
// var re = db.Pr_AddOne(new Pr_AddOne { A = 1 });
// Assert.IsTrue(re != null);
// Assert.IsTrue(re.Any());
// var first = re.First();
// Assert.IsTrue(first.Aa == 2);
//}
}
}
}

View File

@ -6,6 +6,7 @@ using System.Reflection;
using Microsoft.EntityFrameworkCore;
using Microsoft.EntityFrameworkCore.Infrastructure;
using System;
using Microsoft.EntityFrameworkCore.Storage;
namespace Falcon.ModelSP
{
@ -42,6 +43,61 @@ namespace Falcon.ModelSP
return db.Database.SqlQuery<TResultType>(getProcuderName<TPrarmType>(),parms.ToArray()).ToList();
}
/// <summary>
/// 通过存储过程参数模型及参数模型定义的返回类型执行查询
/// </summary>
/// <typeparam name="T">存储过程参数类型</typeparam>
/// <param name="db">数据库上下文</param>
/// <param name="data">参数数据</param>
/// <returns>存储过程结果集</returns>
public static IEnumerable<object> RunSPQuery<T>(this DbContext db,T data) {
var attr = typeof(T).GetCustomAttribute<FalconSPReturnTypeAttribute>(false);
if(attr == null) {
throw new Exception("参数类必须定义FalconSPReturnTypeAttribute特性否则需要明确指定返回值类型");
}
var type = attr.ReturnType;
return RunSPQuery(db,data,typeof(T),type);
}
/// <summary>
/// 通过提供的参数,参数类型和返回类型执行存储过程
/// </summary>
/// <param name="db">数据库上下文</param>
/// <param name="data"></param>
/// <param name="parasType">参数类型</param>
/// <param name="returnType">返回类型</param>
/// <returns></returns>
public static IEnumerable<object> RunSPQuery(DbContext db,object data,Type parasType,Type returnType) {
var pm = getProcuderName(parasType);
var paras = getParams(data).ToArray();
var connection = db.Database.GetDbConnection();
using(var cmd = connection.CreateCommand()) {
cmd.CommandText = pm;
cmd.CommandType = System.Data.CommandType.StoredProcedure;
cmd.Parameters.AddRange(paras);
connection.Open();
var dr = cmd.ExecuteReader();
var result = new List<object>();
if(!dr.CanGetColumnSchema())
return result;
while(dr.Read()) {
var item = returnType.Assembly.CreateInstance(returnType.FullName);
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 = parasType.getProperty(name);
if(pi == null || !pi.CanWrite)
continue;
pi.SetValue(item,value);
}
result.Add(item);
}
connection.Close();
return result;
}
}
/// <summary>
/// 获取存储过程参数枚举
/// </summary>
@ -88,6 +144,18 @@ namespace Falcon.ModelSP
return typeof(T).Name;
}
/// <summary>
/// 获取存储过程名
/// </summary>
/// <param name="type">类型</param>
public static string getProcuderName(Type type) {
var attr = type.GetCustomAttribute<FalconSPProcuderNameAttribute>(true);
if(attr != null && attr is FalconSPProcuderNameAttribute pna && !string.IsNullOrEmpty(pna.ProcuderName)) {
return pna.ProcuderName;
}
return type.Name;
}
/// <summary>
/// 根据传入的sql语句和参数枚举执行存储过程并且返回类型枚举
/// </summary>
@ -125,12 +193,22 @@ namespace Falcon.ModelSP
return result;
}
}
/// <summary>
/// 忽略大小写获取类型的属性
/// </summary>
private static PropertyInfo getProperty<T>(string name) {
var type = typeof(T);
foreach(var item in type.GetProperties()) {
return getProperty(typeof(T),name);
}
/// <summary>
/// 忽略大小写获取类型的属性
/// </summary>
/// <param name="t">类型</param>
/// <param name="name">属性名称</param>
/// <returns>属性</returns>
private static PropertyInfo getProperty(this Type t,string name) {
foreach(var item in t.GetProperties()) {
if(item.Name.ToLower() == name.ToLower()) {
return item;
}

View File

@ -3,12 +3,12 @@
<PropertyGroup>
<TargetFrameworks>netstandard2.0;netstandard2.1</TargetFrameworks>
<GeneratePackageOnBuild>true</GeneratePackageOnBuild>
<AssemblyVersion>1.0.3.0</AssemblyVersion>
<FileVersion>1.0.3.0</FileVersion>
<Version>1.0.3</Version>
<AssemblyVersion>1.0.4.0</AssemblyVersion>
<FileVersion>1.0.4.0</FileVersion>
<Version>1.0.4</Version>
<DocumentationFile>bin\$(Configuration)\$(TargetFramework)\$(AssemblyName).xml</DocumentationFile>
<PackageProjectUrl>http://39.105.71.191/Falcon/Falcon.ModelSP</PackageProjectUrl>
<RepositoryUrl>http://39.105.71.191/Falcon/Falcon.ModelSP</RepositoryUrl>
<PackageProjectUrl>http://106.14.65.137/Falcon/Falcon.ModelSP</PackageProjectUrl>
<RepositoryUrl>http://106.14.65.137/Falcon/Falcon.ModelSP</RepositoryUrl>
<Description>EF Core 存储过程执行组件,可以模型化执行存储过程</Description>
<Authors>Falcon</Authors>
</PropertyGroup>

View File

@ -5,6 +5,7 @@ namespace Falcon.ModelSP
/// <summary>
/// 定义存储过程名称
/// </summary>
[AttributeUsage(AttributeTargets.Class)]
public class FalconSPProcuderNameAttribute:Attribute
{
/// <summary>

View File

@ -0,0 +1,21 @@
using System;
namespace Falcon.ModelSP
{
/// <summary>
/// 定义存储过程返回值类型
/// </summary>
[AttributeUsage(AttributeTargets.Class,AllowMultiple =false,Inherited =false)]
public class FalconSPReturnTypeAttribute:Attribute
{
/// <summary>
/// 返回的数据类型
/// </summary>
public Type ReturnType { get; set; }
/// <summary>
/// 定义存储过程名称
/// </summary>
/// <param name="t">存储过程返回值类型</param>
public FalconSPReturnTypeAttribute(Type t) => this.ReturnType = t;
}
}

View File

@ -27,8 +27,32 @@ namespace Falcon.ModelSP
/// <param name="data">存储过程参数</param>
/// <returns>返回数据枚举</returns>
public IEnumerable<TResultType> RunSP<TPrarmType, TResultType>(DbContext db,TPrarmType data)
where TResultType : class, new() {
return RunSPQuery<TPrarmType,TResultType>(db,data);
}
/// <summary>
/// 执行存储过程
/// </summary>
/// <typeparam name="TPrarmType">参数类型</typeparam>
/// <typeparam name="TResultType">返回值枚举的类型</typeparam>
/// <param name="db">数据上下文</param>
/// <param name="data">存储过程参数</param>
/// <returns>返回数据枚举</returns>
public IEnumerable<TResultType> RunSPQuery<TPrarmType, TResultType>(DbContext db,TPrarmType data)
where TResultType : class, new() {
return db.RunProcuder<TPrarmType,TResultType>(data);
}
/// <summary>
/// 根据模型定义参数执行存储过程进行查询参数类型必须定义FalconSPReturnTypeAttribute特性
/// </summary>
/// <typeparam name="TPrarmType">存储过程参数类型</typeparam>
/// <param name="db">数据上下文</param>
/// <param name="data">存储过程参数</param>
/// <returns>返回类型枚举FalconSPReturnTypeAttribute定义的类型枚举。</returns>
public IEnumerable<object> RunSPQuery<TPrarmType>(DbContext db,TPrarmType data) {
return db.RunSPQuery(data);
}
}
}

View File

@ -24,5 +24,23 @@ namespace Falcon.ModelSP
/// <param name="db">数据上下文</param>
/// <param name="data">参数数据</param>
IEnumerable<TResultType> RunSP<TPrarmType, TResultType>(DbContext db,TPrarmType data) where TResultType : class, new();
/// <summary>
/// 通过数据库上下文执行存储过程,并返回查询结果
/// </summary>
/// <typeparam name="TPrarmType">参数类型</typeparam>
/// <typeparam name="TResultType">返回结果项类型</typeparam>
/// <param name="db">数据上下文</param>
/// <param name="data">参数数据</param>
IEnumerable<TResultType> RunSPQuery<TPrarmType, TResultType>(DbContext db,TPrarmType data) where TResultType : class, new();
/// <summary>
/// 根据模型定义参数执行存储过程进行查询参数类型必须定义FalconSPReturnTypeAttribute特性
/// </summary>
/// <typeparam name="TPrarmType">存储过程参数类型</typeparam>
/// <param name="db">数据上下文</param>
/// <param name="data">存储过程参数</param>
/// <returns>返回类型枚举FalconSPReturnTypeAttribute定义的类型枚举。</returns>
IEnumerable<object> RunSPQuery<TPrarmType>(DbContext db,TPrarmType data);
}
}