mirror of
https://github.com/FalconWu2017/Falcon.StoredProcedureRunner.git
synced 2024-11-23 05:29:37 +08:00
发布2.1版本,支持Oracle和SqlServer
This commit is contained in:
parent
2bcbeb4dae
commit
177d648979
|
@ -2,3 +2,10 @@
|
||||||
|
|
||||||
# CS8618: 在退出构造函数时,不可为 null 的字段必须包含非 null 值。请考虑声明为可以为 null。
|
# CS8618: 在退出构造函数时,不可为 null 的字段必须包含非 null 值。请考虑声明为可以为 null。
|
||||||
dotnet_diagnostic.CS8618.severity = none
|
dotnet_diagnostic.CS8618.severity = none
|
||||||
|
|
||||||
|
# CS1591: 缺少对公共可见类型或成员的 XML 注释
|
||||||
|
dotnet_diagnostic.CS1591.severity = none
|
||||||
|
|
||||||
|
[*.{cs,vb}]
|
||||||
|
dotnet_style_qualification_for_property=true:suggestion
|
||||||
|
dotnet_style_qualification_for_method=false:suggestion
|
|
@ -1,6 +1,6 @@
|
||||||
using System;
|
using System;
|
||||||
|
|
||||||
namespace Falcon.StoredProcedureRunner
|
namespace Falcon.StoredProcedureRunner.Attributes
|
||||||
{
|
{
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// 表示调用时候忽略此属性
|
/// 表示调用时候忽略此属性
|
|
@ -1,7 +1,7 @@
|
||||||
using System;
|
using System;
|
||||||
using System.Data;
|
using System.Data;
|
||||||
|
|
||||||
namespace Falcon.StoredProcedureRunner
|
namespace Falcon.StoredProcedureRunner.Attributes
|
||||||
{
|
{
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// 定义存储过程参数方向。默认Input
|
/// 定义存储过程参数方向。默认Input
|
|
@ -1,6 +1,6 @@
|
||||||
using System;
|
using System;
|
||||||
|
|
||||||
namespace Falcon.StoredProcedureRunner
|
namespace Falcon.StoredProcedureRunner.Attributes
|
||||||
{
|
{
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// 定义名称
|
/// 定义名称
|
|
@ -0,0 +1,39 @@
|
||||||
|
using System;
|
||||||
|
|
||||||
|
namespace Falcon.StoredProcedureRunner.Attributes
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// 定义存储过程参数类型
|
||||||
|
/// </summary>
|
||||||
|
[AttributeUsage(AttributeTargets.Property, AllowMultiple = false, Inherited = false)]
|
||||||
|
public class FalconSPPrarmTypeAttribute : Attribute
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// 参数名
|
||||||
|
/// </summary>
|
||||||
|
public FalconSPDbType PType { get; set; }
|
||||||
|
/// <summary>
|
||||||
|
/// 数据长度
|
||||||
|
/// </summary>
|
||||||
|
public int? Size { get; set; }
|
||||||
|
/// <summary>
|
||||||
|
/// 定于存储过程参数名称
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="pDbType">参数类型.DbType</param>
|
||||||
|
/// <param name="size">类型长度</param>
|
||||||
|
public FalconSPPrarmTypeAttribute(FalconSPDbType pDbType, int size)
|
||||||
|
{
|
||||||
|
this.PType = pDbType;
|
||||||
|
this.Size = size;
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 定于存储过程参数名称
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="pDbType">参数类型.DbType</param>
|
||||||
|
public FalconSPPrarmTypeAttribute(FalconSPDbType pDbType) {
|
||||||
|
this.PType = pDbType;
|
||||||
|
this.Size = null;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -1,6 +1,6 @@
|
||||||
using System;
|
using System;
|
||||||
|
|
||||||
namespace Falcon.StoredProcedureRunner
|
namespace Falcon.StoredProcedureRunner.Attributes
|
||||||
{
|
{
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// 定义存储过程名称
|
/// 定义存储过程名称
|
|
@ -1,12 +1,12 @@
|
||||||
using System;
|
using System;
|
||||||
|
|
||||||
namespace Falcon.StoredProcedureRunner
|
namespace Falcon.StoredProcedureRunner.Attributes
|
||||||
{
|
{
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// 定义存储过程返回值类型
|
/// 定义存储过程返回值类型
|
||||||
/// </summary>
|
/// </summary>
|
||||||
[AttributeUsage(AttributeTargets.Class,AllowMultiple = false,Inherited = false)]
|
[AttributeUsage(AttributeTargets.Class, AllowMultiple = false, Inherited = false)]
|
||||||
public class FalconSPReturnTypeAttribute:Attribute
|
public class FalconSPReturnTypeAttribute : Attribute
|
||||||
{
|
{
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// 返回的数据类型
|
/// 返回的数据类型
|
|
@ -0,0 +1,21 @@
|
||||||
|
using System;
|
||||||
|
|
||||||
|
namespace Falcon.StoredProcedureRunner.Attributes
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// 定义存储过程返回临时表名称。主要应用与oracle数据库通过临时表返回结果。
|
||||||
|
/// </summary>
|
||||||
|
[AttributeUsage(AttributeTargets.Class, AllowMultiple = false, Inherited = false)]
|
||||||
|
public class FalconSPTempTableAttribute : Attribute
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// 存储返回临时表名称
|
||||||
|
/// </summary>
|
||||||
|
public string TableName { get; set; }
|
||||||
|
/// <summary>
|
||||||
|
/// 定义存储返回临时表名称
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="name">临时表名称</param>
|
||||||
|
public FalconSPTempTableAttribute(string name) => TableName=name;
|
||||||
|
}
|
||||||
|
}
|
|
@ -3,7 +3,7 @@
|
||||||
namespace Falcon.StoredProcedureRunner
|
namespace Falcon.StoredProcedureRunner
|
||||||
{
|
{
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// 设置返回对象值时候发生异常
|
/// 不支持的数据库类型
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public class DatabaseNotSupportedException : Exception
|
public class DatabaseNotSupportedException : Exception
|
||||||
{
|
{
|
|
@ -3,7 +3,7 @@
|
||||||
<PropertyGroup>
|
<PropertyGroup>
|
||||||
<TargetFrameworks>net5.0</TargetFrameworks>
|
<TargetFrameworks>net5.0</TargetFrameworks>
|
||||||
<GeneratePackageOnBuild>true</GeneratePackageOnBuild>
|
<GeneratePackageOnBuild>true</GeneratePackageOnBuild>
|
||||||
<Version>2.0.0</Version>
|
<Version>2.1.0</Version>
|
||||||
<DocumentationFile>bin\$(Configuration)\$(TargetFramework)\$(AssemblyName).xml</DocumentationFile>
|
<DocumentationFile>bin\$(Configuration)\$(TargetFramework)\$(AssemblyName).xml</DocumentationFile>
|
||||||
<PackageProjectUrl>https://github.com/FalconWu2017/Falcon.StoredProcedureRunner</PackageProjectUrl>
|
<PackageProjectUrl>https://github.com/FalconWu2017/Falcon.StoredProcedureRunner</PackageProjectUrl>
|
||||||
<RepositoryUrl>https://github.com/FalconWu2017/Falcon.StoredProcedureRunner</RepositoryUrl>
|
<RepositoryUrl>https://github.com/FalconWu2017/Falcon.StoredProcedureRunner</RepositoryUrl>
|
||||||
|
|
|
@ -6,6 +6,7 @@
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public enum FalconSPDbType
|
public enum FalconSPDbType
|
||||||
{
|
{
|
||||||
|
#pragma warning disable CS1591 // 缺少对公共可见类型或成员的 XML 注释
|
||||||
//
|
//
|
||||||
// 摘要:
|
// 摘要:
|
||||||
// System.Int64. A 64-bit signed integer.
|
// System.Int64. A 64-bit signed integer.
|
||||||
|
@ -201,7 +202,6 @@
|
||||||
OracleBoolean = 134,
|
OracleBoolean = 134,
|
||||||
OracleJson = 135
|
OracleJson = 135
|
||||||
|
|
||||||
|
#pragma warning restore CS1591 // 缺少对公共可见类型或成员的 XML 注释
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,21 +0,0 @@
|
||||||
using System;
|
|
||||||
|
|
||||||
namespace Falcon.StoredProcedureRunner
|
|
||||||
{
|
|
||||||
/// <summary>
|
|
||||||
/// 定义存储过程参数类型
|
|
||||||
/// </summary>
|
|
||||||
[AttributeUsage(AttributeTargets.Property, AllowMultiple = false, Inherited = false)]
|
|
||||||
public class FalconSPPrarmTypeAttribute:Attribute
|
|
||||||
{
|
|
||||||
/// <summary>
|
|
||||||
/// 参数名
|
|
||||||
/// </summary>
|
|
||||||
public FalconSPDbType PType { get; set; }
|
|
||||||
/// <summary>
|
|
||||||
/// 定于存储过程参数名称
|
|
||||||
/// </summary>
|
|
||||||
/// <param name="pDbType">参数类型.DbType</param>
|
|
||||||
public FalconSPPrarmTypeAttribute(FalconSPDbType pDbType) { this.PType = pDbType; }
|
|
||||||
}
|
|
||||||
}
|
|
7
src/Falcon.StoredProcedureRunner/IOracleRunner.cs
Normal file
7
src/Falcon.StoredProcedureRunner/IOracleRunner.cs
Normal file
|
@ -0,0 +1,7 @@
|
||||||
|
namespace Falcon.StoredProcedureRunner
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// 面向Oracle的执行器
|
||||||
|
/// </summary>
|
||||||
|
public interface IOracleRunner : IRunner { }
|
||||||
|
}
|
|
@ -15,7 +15,7 @@ namespace Falcon.StoredProcedureRunner
|
||||||
/// <typeparam name="TPrarmType">参数类型</typeparam>
|
/// <typeparam name="TPrarmType">参数类型</typeparam>
|
||||||
/// <param name="db">数据上下文</param>
|
/// <param name="db">数据上下文</param>
|
||||||
/// <param name="data">参数数据</param>
|
/// <param name="data">参数数据</param>
|
||||||
int Execute<TPrarmType>(DbContext db,TPrarmType data);
|
int Execute<TPrarmType>(DbContext db, TPrarmType data);
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// 通过数据库上下文执行存储过程,并返回查询结果
|
/// 通过数据库上下文执行存储过程,并返回查询结果
|
||||||
|
@ -25,7 +25,7 @@ namespace Falcon.StoredProcedureRunner
|
||||||
/// <param name="returnType">返回结果项类型</param>
|
/// <param name="returnType">返回结果项类型</param>
|
||||||
/// <param name="data">执行参数</param>
|
/// <param name="data">执行参数</param>
|
||||||
/// <returns>查询结果枚举</returns>
|
/// <returns>查询结果枚举</returns>
|
||||||
IEnumerable<object> Run(DbContext db,Type prarmType,Type returnType ,object data) ;
|
IEnumerable<object> Run(DbContext db, Type prarmType, Type returnType, object data);
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// (存在sql注入风险)执行Sql语句,并将数据库返回结果以json数据对象返回。
|
/// (存在sql注入风险)执行Sql语句,并将数据库返回结果以json数据对象返回。
|
||||||
|
@ -33,6 +33,6 @@ namespace Falcon.StoredProcedureRunner
|
||||||
/// <param name="db">数据上下文</param>
|
/// <param name="db">数据上下文</param>
|
||||||
/// <param name="sql">要执行的sql语句</param>
|
/// <param name="sql">要执行的sql语句</param>
|
||||||
/// <returns>数据库返回值json格式</returns>
|
/// <returns>数据库返回值json格式</returns>
|
||||||
string RunRaw(DbContext db,string sql);
|
string RunRaw(DbContext db, string sql);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -4,6 +4,7 @@ using System.Linq;
|
||||||
using System.Reflection;
|
using System.Reflection;
|
||||||
using System.Runtime.CompilerServices;
|
using System.Runtime.CompilerServices;
|
||||||
using System.Text;
|
using System.Text;
|
||||||
|
using Falcon.StoredProcedureRunner.Attributes;
|
||||||
using Microsoft.EntityFrameworkCore;
|
using Microsoft.EntityFrameworkCore;
|
||||||
|
|
||||||
namespace Falcon.StoredProcedureRunner
|
namespace Falcon.StoredProcedureRunner
|
||||||
|
|
|
@ -1,4 +1,5 @@
|
||||||
using Microsoft.Extensions.DependencyInjection;
|
using Microsoft.Extensions.DependencyInjection;
|
||||||
|
using Microsoft.Extensions.Configuration;
|
||||||
|
|
||||||
namespace Falcon.StoredProcedureRunner
|
namespace Falcon.StoredProcedureRunner
|
||||||
{
|
{
|
||||||
|
@ -12,7 +13,8 @@ namespace Falcon.StoredProcedureRunner
|
||||||
/// </summary>
|
/// </summary>
|
||||||
/// <param name="services">注册服务集合</param>
|
/// <param name="services">注册服务集合</param>
|
||||||
/// <returns>服务集合</returns>
|
/// <returns>服务集合</returns>
|
||||||
public static IServiceCollection UseFalconSPRunner(this IServiceCollection services) {
|
public static IServiceCollection UseFalconSPRunner(this IServiceCollection services)
|
||||||
|
{
|
||||||
return services.AddFalconSPRunner();
|
return services.AddFalconSPRunner();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -21,8 +23,12 @@ namespace Falcon.StoredProcedureRunner
|
||||||
/// </summary>
|
/// </summary>
|
||||||
/// <param name="services">注册服务集合</param>
|
/// <param name="services">注册服务集合</param>
|
||||||
/// <returns>服务集合</returns>
|
/// <returns>服务集合</returns>
|
||||||
public static IServiceCollection AddFalconSPRunner(this IServiceCollection services) {
|
public static IServiceCollection AddFalconSPRunner(this IServiceCollection services)
|
||||||
return services.AddSingleton<IRunner,Runner>();
|
{
|
||||||
|
services.AddSingleton<IRunner, Runner>();
|
||||||
|
services.AddSingleton<IOracleRunner, OracleRunner>();
|
||||||
|
services.AddSingleton<ISqlServerRunner, SqlServerRunner>();
|
||||||
|
return services;
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
7
src/Falcon.StoredProcedureRunner/ISqlServerRunner.cs
Normal file
7
src/Falcon.StoredProcedureRunner/ISqlServerRunner.cs
Normal file
|
@ -0,0 +1,7 @@
|
||||||
|
namespace Falcon.StoredProcedureRunner
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// 面向SqlServer的执行器
|
||||||
|
/// </summary>
|
||||||
|
public interface ISqlServerRunner : IRunner { }
|
||||||
|
}
|
124
src/Falcon.StoredProcedureRunner/OracleRunner.cs
Normal file
124
src/Falcon.StoredProcedureRunner/OracleRunner.cs
Normal file
|
@ -0,0 +1,124 @@
|
||||||
|
using Microsoft.Data.SqlClient;
|
||||||
|
using Microsoft.EntityFrameworkCore;
|
||||||
|
using Microsoft.Extensions.Options;
|
||||||
|
using Oracle.ManagedDataAccess.Client;
|
||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.Data;
|
||||||
|
using System.Data.Common;
|
||||||
|
using System.Linq;
|
||||||
|
using System.Transactions;
|
||||||
|
|
||||||
|
namespace Falcon.StoredProcedureRunner
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// 面向Oracle的执行器
|
||||||
|
/// </summary>
|
||||||
|
public class OracleRunner : RunnerBase, IOracleRunner
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// 执行参数
|
||||||
|
/// </summary>
|
||||||
|
public OracleRunnerOptions Options { get; set; }
|
||||||
|
/// <summary>
|
||||||
|
/// 通过提供构造选项构造Oracle执行器
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="option">选项</param>
|
||||||
|
public OracleRunner(IOptions<OracleRunnerOptions> option = null)
|
||||||
|
{
|
||||||
|
this.Options = option?.Value ?? new OracleRunnerOptions();
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 创建存储过程参数
|
||||||
|
/// </summary>
|
||||||
|
protected override IDataParameter CreateDbParameter(string name, object val, int? type, int? size)
|
||||||
|
{
|
||||||
|
DbParameter par =
|
||||||
|
type.HasValue && size.HasValue ? new OracleParameter(name, (OracleDbType)type, size.Value) :
|
||||||
|
type.HasValue && !size.HasValue ? new OracleParameter(name, (OracleDbType)type) :
|
||||||
|
!type.HasValue && !size.HasValue ? new OracleParameter(name, val) :
|
||||||
|
null;
|
||||||
|
par.Value = val;
|
||||||
|
return par as IDataParameter;
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 表是否存在
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="db">数据库上下文</param>
|
||||||
|
/// <param name="tableName">表名称</param>
|
||||||
|
/// <returns>存在True,不存在False</returns>
|
||||||
|
protected override bool IsTableExists(DbContext db, string tableName)
|
||||||
|
{
|
||||||
|
throw new System.NotImplementedException();
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 获取Oracle数据库链接
|
||||||
|
/// </summary>
|
||||||
|
protected override DbConnection GetDbConnection(DbContext context)
|
||||||
|
{
|
||||||
|
return context.Database.GetDbConnection() as OracleConnection;
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 获取数据库前缀
|
||||||
|
/// </summary>
|
||||||
|
/// <returns>前缀</returns>
|
||||||
|
protected override string GetParamProfix()
|
||||||
|
{
|
||||||
|
return ":";
|
||||||
|
}
|
||||||
|
|
||||||
|
public override IEnumerable<object> Run(DbContext db, Type prarmType, Type returnType, object data)
|
||||||
|
{
|
||||||
|
return this.Options.ReturnModel switch
|
||||||
|
{
|
||||||
|
ReturnModel.Return => RunByReturn(db, prarmType, returnType, data),
|
||||||
|
ReturnModel.TempTable => RunByTempTable(db, prarmType, returnType, data),
|
||||||
|
_ => throw new NotSupportedException(),
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
protected IEnumerable<object> RunByReturn(DbContext db, Type prarmType, Type returnType, object data)
|
||||||
|
{
|
||||||
|
var pm = GetProcuderName(prarmType);
|
||||||
|
var paras = getParams(prarmType, data).ToArray();
|
||||||
|
DataSet ds = new();
|
||||||
|
var conn = db.Database.GetDbConnection() as OracleConnection;
|
||||||
|
using var cmd = conn.CreateCommand();
|
||||||
|
cmd.CommandType = CommandType.StoredProcedure;
|
||||||
|
cmd.CommandText = pm;
|
||||||
|
cmd.Parameters.AddRange(paras);
|
||||||
|
var da = new OracleDataAdapter(cmd);
|
||||||
|
da.Fill(ds);
|
||||||
|
cmd.Parameters.Clear();
|
||||||
|
return DataSetToIEnumerable(ds, returnType);
|
||||||
|
}
|
||||||
|
|
||||||
|
protected IEnumerable<object> RunByTempTable(DbContext db, Type prarmType, Type returnType, object data)
|
||||||
|
{
|
||||||
|
var pm = GetProcuderName(prarmType);
|
||||||
|
var paras = getParams(prarmType, data).ToArray();
|
||||||
|
var tempTable = GetTempTableName(returnType);
|
||||||
|
using TransactionScope tran = new(TransactionScopeOption.Required);
|
||||||
|
using var cmd = db.Database.GetDbConnection().CreateCommand() as OracleCommand;
|
||||||
|
cmd.CommandType = CommandType.StoredProcedure;
|
||||||
|
cmd.CommandText = pm;
|
||||||
|
cmd.Parameters.AddRange(paras);
|
||||||
|
//cmd.BindByName = true;
|
||||||
|
db.Database.GetDbConnection().Open();
|
||||||
|
cmd.ExecuteNonQuery();
|
||||||
|
cmd.Parameters.Clear();
|
||||||
|
cmd.CommandText= $"select * from {tempTable}";
|
||||||
|
cmd.CommandType = CommandType.Text;
|
||||||
|
var da = new OracleDataAdapter(cmd);
|
||||||
|
DataSet ds = new();
|
||||||
|
da.Fill(ds);
|
||||||
|
tran.Complete();
|
||||||
|
return DataSetToIEnumerable(ds, returnType);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
13
src/Falcon.StoredProcedureRunner/OracleRunnerOptions.cs
Normal file
13
src/Falcon.StoredProcedureRunner/OracleRunnerOptions.cs
Normal file
|
@ -0,0 +1,13 @@
|
||||||
|
namespace Falcon.StoredProcedureRunner
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// Oracle执行配置
|
||||||
|
/// </summary>
|
||||||
|
public class OracleRunnerOptions
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// 获取数据返回方式 DbReader 1或TempTable 2
|
||||||
|
/// </summary>
|
||||||
|
public ReturnModel ReturnModel { get; set; } = ReturnModel.TempTable;
|
||||||
|
}
|
||||||
|
}
|
17
src/Falcon.StoredProcedureRunner/ReturnModel.cs
Normal file
17
src/Falcon.StoredProcedureRunner/ReturnModel.cs
Normal file
|
@ -0,0 +1,17 @@
|
||||||
|
namespace Falcon.StoredProcedureRunner
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// 获取返回值方式
|
||||||
|
/// </summary>
|
||||||
|
public enum ReturnModel
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// 通过存储过程返回值获取数据
|
||||||
|
/// </summary>
|
||||||
|
Return = 1,
|
||||||
|
/// <summary>
|
||||||
|
/// 通过临时表表获取数据
|
||||||
|
/// </summary>
|
||||||
|
TempTable = 2
|
||||||
|
}
|
||||||
|
}
|
|
@ -1,360 +1,54 @@
|
||||||
using Microsoft.Data.SqlClient;
|
using Microsoft.EntityFrameworkCore;
|
||||||
using Microsoft.EntityFrameworkCore;
|
using Microsoft.Extensions.DependencyInjection;
|
||||||
using Newtonsoft.Json.Linq;
|
|
||||||
using Oracle.ManagedDataAccess.Client;
|
|
||||||
using System;
|
using System;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using System.Data;
|
|
||||||
using System.Data.Common;
|
|
||||||
using System.Linq;
|
|
||||||
using System.Reflection;
|
|
||||||
using System.Text;
|
|
||||||
|
|
||||||
namespace Falcon.StoredProcedureRunner
|
namespace Falcon.StoredProcedureRunner
|
||||||
{
|
{
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// 存储过程执行
|
/// 通用存储过程执行器
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public partial class Runner : IRunner
|
public class Runner : IRunner
|
||||||
{
|
{
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// 执行无返回值的存储过程
|
/// 注册的所有服务
|
||||||
/// </summary>
|
/// </summary>
|
||||||
/// <typeparam name="TPrarmType">参数类型</typeparam>
|
public IServiceProvider Service { get; }
|
||||||
/// <param name="db">数据上下文</param>
|
/// <summary>
|
||||||
/// <param name="data">参数数据</param>
|
/// 通过注册的服务实例化执行器
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="service">服务集合</param>
|
||||||
|
public Runner(IServiceProvider service)
|
||||||
|
{
|
||||||
|
Service = service;
|
||||||
|
}
|
||||||
|
|
||||||
public int Execute<TPrarmType>(DbContext db, TPrarmType data)
|
public int Execute<TPrarmType>(DbContext db, TPrarmType data)
|
||||||
{
|
{
|
||||||
throw new NotSupportedException();
|
return GetRunner(db).Execute<TPrarmType>(db, data);
|
||||||
//var parms = getParams(db, typeof(TPrarmType), data).ToArray();
|
|
||||||
//var pName = getProcuderName<TPrarmType>();
|
|
||||||
//var conn = db.Database.GetDbConnection();
|
|
||||||
|
|
||||||
|
|
||||||
//var paramStr = getParamStr(typeof(TPrarmType), data);
|
|
||||||
//var str = $"exec {pName} {paramStr}";
|
|
||||||
//return db.Database.ExecuteSqlRaw(str, parms);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// 通过数据库上下文执行存储过程,并返回查询结果
|
|
||||||
/// </summary>
|
|
||||||
/// <param name="db">数据库上下文</param>
|
|
||||||
/// <param name="prarmType">参数类型</param>
|
|
||||||
/// <param name="returnType">返回值类型</param>
|
|
||||||
/// <param name="data">存储过程参数</param>
|
|
||||||
/// <returns>查询结果枚举</returns>
|
|
||||||
public IEnumerable<object> Run(DbContext db, Type prarmType, Type returnType, object data)
|
public IEnumerable<object> Run(DbContext db, Type prarmType, Type returnType, object data)
|
||||||
{
|
{
|
||||||
return RunByReader(db, prarmType, returnType, data);
|
return GetRunner(db).Run(db, prarmType, returnType, data);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// 通过数据库上下文执行存储过程,并返回查询结果
|
|
||||||
/// </summary>
|
|
||||||
/// <param name="db">数据库上下文</param>
|
|
||||||
/// <param name="prarmType">参数类型</param>
|
|
||||||
/// <param name="returnType">返回值类型</param>
|
|
||||||
/// <param name="data">存储过程参数</param>
|
|
||||||
/// <returns>查询结果枚举</returns>
|
|
||||||
public IEnumerable<object> RunByReader(DbContext db, Type prarmType, Type returnType, object data)
|
|
||||||
{
|
|
||||||
var pm = getProcuderName(prarmType);
|
|
||||||
var paras = getParams(db, prarmType, data).ToArray();
|
|
||||||
var connection = db.Database.GetDbConnection();
|
|
||||||
using var cmd = connection.CreateCommand();
|
|
||||||
cmd.CommandText = pm;
|
|
||||||
cmd.CommandType = CommandType.StoredProcedure;
|
|
||||||
cmd.Parameters.AddRange(paras);
|
|
||||||
connection.Open();
|
|
||||||
using var dr = cmd.ExecuteReader();
|
|
||||||
var columnSchema = dr.GetColumnSchema();
|
|
||||||
var result = new List<object>();
|
|
||||||
if (!dr.CanGetColumnSchema())
|
|
||||||
return result;
|
|
||||||
int rowId = 0;
|
|
||||||
while (dr.Read())
|
|
||||||
{
|
|
||||||
var item = returnType.Assembly.CreateInstance(returnType.FullName);
|
|
||||||
for (var i = 0; i < columnSchema.Count; i++)
|
|
||||||
{
|
|
||||||
var name = dr.GetName(i);
|
|
||||||
var value = dr.IsDBNull(i) ? null : dr.GetValue(i);
|
|
||||||
var pi = getProperty(returnType, name);
|
|
||||||
if (pi == null || !pi.CanWrite)
|
|
||||||
continue;
|
|
||||||
try
|
|
||||||
{
|
|
||||||
pi.SetValue(item, value);
|
|
||||||
}
|
|
||||||
catch (Exception ex)
|
|
||||||
{
|
|
||||||
throw new ReturnDataSetValueException(rowId, name, pi, value, ex);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
result.Add(item);
|
|
||||||
rowId++;
|
|
||||||
}
|
|
||||||
connection.Close();
|
|
||||||
return result;
|
|
||||||
}
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// 通过数据库上下文执行存储过程,并返回查询结果
|
|
||||||
/// </summary>
|
|
||||||
/// <param name="db">数据库上下文</param>
|
|
||||||
/// <param name="prarmType">参数类型</param>
|
|
||||||
/// <param name="returnType">返回值类型</param>
|
|
||||||
/// <param name="data">存储过程参数</param>
|
|
||||||
/// <returns>查询结果枚举</returns>
|
|
||||||
public IEnumerable<object> RunByDbset(DbContext db, Type prarmType, Type returnType, object data)
|
|
||||||
{
|
|
||||||
var result = new List<object>();
|
|
||||||
var pm = getProcuderName(prarmType);
|
|
||||||
var paras = getParams(db, prarmType, data).ToArray();
|
|
||||||
DbConnection connection = db.Database.GetDbConnection();
|
|
||||||
DataSet ds = new DataSet();
|
|
||||||
if (db.Database.IsOracle())
|
|
||||||
{
|
|
||||||
var conn = db.Database.GetDbConnection() as OracleConnection;
|
|
||||||
using var cmd = new OracleCommand(pm, conn);
|
|
||||||
cmd.CommandType = CommandType.StoredProcedure;
|
|
||||||
cmd.Parameters.AddRange(paras);
|
|
||||||
var da = new OracleDataAdapter(cmd);
|
|
||||||
da.Fill(ds);
|
|
||||||
}
|
|
||||||
else if (db.Database.IsSqlServer())
|
|
||||||
{
|
|
||||||
var oracleConn = db.Database.GetDbConnection() as SqlConnection;
|
|
||||||
using var oracleCmd = new SqlCommand(pm, oracleConn);
|
|
||||||
oracleCmd.CommandType = CommandType.StoredProcedure;
|
|
||||||
oracleCmd.Parameters.AddRange(paras);
|
|
||||||
var da = new SqlDataAdapter(oracleCmd);
|
|
||||||
da.Fill(ds);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
throw new DatabaseNotSupportedException();
|
|
||||||
}
|
|
||||||
var rows = ds.Tables[0].Rows;
|
|
||||||
var cols = ds.Tables[0].Columns;
|
|
||||||
for (int i = 0; i < rows.Count; i++)
|
|
||||||
{
|
|
||||||
var item = returnType.Assembly.CreateInstance(returnType.FullName);
|
|
||||||
var row = rows[i];
|
|
||||||
for (int y = 0; y < cols.Count; y++)
|
|
||||||
{
|
|
||||||
var name = cols[y].ColumnName;
|
|
||||||
var val = row[y] is DBNull ? null : row[y];
|
|
||||||
var pi = getProperty(returnType, name);
|
|
||||||
if (pi == null || !pi.CanWrite)
|
|
||||||
continue;
|
|
||||||
try
|
|
||||||
{
|
|
||||||
pi.SetValue(item, val);
|
|
||||||
}
|
|
||||||
catch (Exception ex)
|
|
||||||
{
|
|
||||||
throw new ReturnDataSetValueException(i, name, pi, val, ex);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
result.Add(item);
|
|
||||||
}
|
|
||||||
connection.Close();
|
|
||||||
return result;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// (存在sql注入风险)执行Sql语句,并将数据库返回结果以json数据对象返回。
|
|
||||||
/// </summary>
|
|
||||||
/// <param name="db">数据上下文</param>
|
|
||||||
/// <param name="sql">要执行的sql语句</param>
|
|
||||||
/// <returns>数据库返回值json格式</returns>
|
|
||||||
public string RunRaw(DbContext db, string sql)
|
public string RunRaw(DbContext db, string sql)
|
||||||
{
|
{
|
||||||
var connection = db.Database.GetDbConnection();
|
return GetRunner(db).RunRaw(db, sql);
|
||||||
using (var cmd = connection.CreateCommand())
|
|
||||||
{
|
|
||||||
cmd.CommandText = sql;
|
|
||||||
cmd.CommandType = System.Data.CommandType.Text;
|
|
||||||
connection.Open();
|
|
||||||
var dr = cmd.ExecuteReader();
|
|
||||||
var result = new StringBuilder();
|
|
||||||
if (!dr.CanGetColumnSchema())
|
|
||||||
return "";
|
|
||||||
while (dr.Read())
|
|
||||||
{
|
|
||||||
var item = new StringBuilder();
|
|
||||||
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);
|
|
||||||
item.Append($"\"{name}\":\"{value}\",");
|
|
||||||
}
|
|
||||||
result.Append($"{{{item.ToString().TrimEnd(',')}}},");
|
|
||||||
}
|
|
||||||
connection.Close();
|
|
||||||
return "[" + result.ToString().TrimEnd(',') + "]";
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// 内部保护方法
|
|
||||||
/// </summary>
|
|
||||||
public partial class Runner
|
|
||||||
{
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// 获取存储过程名
|
/// 获取特定类型的数据库runnner
|
||||||
/// </summary>
|
|
||||||
/// <param name="pramType">参数类型</param>
|
|
||||||
private static string getProcuderName(Type pramType)
|
|
||||||
{
|
|
||||||
var attr = pramType.GetCustomAttribute<FalconSPProcuderNameAttribute>();
|
|
||||||
return attr?.ProcuderName ?? pramType.Name;
|
|
||||||
}
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// 获取存储过程参数枚举
|
|
||||||
/// </summary>
|
|
||||||
///<param name="type">数据的类型</param>
|
|
||||||
/// <param name="data">参数实例</param>
|
|
||||||
private static IEnumerable<IDataParameter> getParams(DbContext db, Type type, object data)
|
|
||||||
{
|
|
||||||
if (data == null)
|
|
||||||
yield break;
|
|
||||||
var fixC =
|
|
||||||
db.Database.IsOracle() ? ":" :
|
|
||||||
db.Database.IsSqlServer() ? "@" :
|
|
||||||
throw new DatabaseNotSupportedException();
|
|
||||||
|
|
||||||
foreach (var p in type.GetProperties())
|
|
||||||
{
|
|
||||||
if (!p.CanRead || isIgnoreProp(p))
|
|
||||||
continue;
|
|
||||||
var name = getPrarmName(p, fixC);
|
|
||||||
var val = p.GetValue(data);
|
|
||||||
var pt = getPrarmType(p);
|
|
||||||
var para = CreateDbParameter(db, name, val, pt);
|
|
||||||
para.Direction = GetParaDirection(p);
|
|
||||||
yield return para;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// 获取存储过程参数类型
|
|
||||||
/// </summary>
|
|
||||||
/// <param name="p">对应的属性</param>
|
|
||||||
private static int? getPrarmType(PropertyInfo p)
|
|
||||||
{
|
|
||||||
var np = p.GetCustomAttribute<FalconSPPrarmTypeAttribute>();
|
|
||||||
if (np != null && np is FalconSPPrarmTypeAttribute na)
|
|
||||||
{
|
|
||||||
return (int)np.PType;
|
|
||||||
}
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// 创建存储过程参数
|
|
||||||
/// </summary>
|
/// </summary>
|
||||||
/// <param name="db">数据库上下文</param>
|
/// <param name="db">数据库上下文</param>
|
||||||
/// <param name="name">参数名称</param>
|
/// <returns>特定类型的执行器</returns>
|
||||||
/// <param name="val">参数值</param>
|
/// <exception cref="DatabaseNotSupportedException"></exception>
|
||||||
/// <returns>参数</returns>
|
protected IRunner GetRunner(DbContext db)
|
||||||
private static IDataParameter CreateDbParameter(DbContext db, string name, object val, int? type)
|
|
||||||
{
|
{
|
||||||
var dbf = db.Database;
|
return
|
||||||
if (type.HasValue)
|
db.Database.IsOracle() ? Service.GetService<IOracleRunner>() :
|
||||||
{
|
db.Database.IsSqlServer() ? Service.GetService<IOracleRunner>() :
|
||||||
IDataParameter pra =
|
throw new DatabaseNotSupportedException();
|
||||||
dbf.IsOracle() ? new OracleParameter(name, (OracleDbType)type) :
|
|
||||||
dbf.IsSqlServer() ? new SqlParameter(name, (SqlDbType)type) :
|
|
||||||
throw new DatabaseNotSupportedException();
|
|
||||||
pra.Value = val;
|
|
||||||
return pra;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
return
|
|
||||||
dbf.IsSqlServer() ? new SqlParameter(name, val) :
|
|
||||||
dbf.IsOracle() ? new OracleParameter(name, val) :
|
|
||||||
throw new DatabaseNotSupportedException();
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// 获取参数的方向。默认Input
|
|
||||||
/// </summary>
|
|
||||||
/// <param name="p">参数映射属性</param>
|
|
||||||
/// <returns>方向或null</returns>
|
|
||||||
private static ParameterDirection GetParaDirection(PropertyInfo p)
|
|
||||||
{
|
|
||||||
var attr = p.GetCustomAttribute<FalconSPPrarmDirectionAttribute>();
|
|
||||||
return attr == null ? ParameterDirection.Input : attr.Direction;
|
|
||||||
}
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// 是否忽略属性
|
|
||||||
/// </summary>
|
|
||||||
/// <param name="p">要检查的属性</param>
|
|
||||||
private static bool isIgnoreProp(PropertyInfo p)
|
|
||||||
{
|
|
||||||
return p.GetCustomAttribute<FalconSPIgnoreAttribute>(true) != null;
|
|
||||||
}
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// 获取存储过程参数名称
|
|
||||||
/// </summary>
|
|
||||||
/// <param name="p">对应的属性</param>
|
|
||||||
private static string getPrarmName(PropertyInfo p, string prefixChar)
|
|
||||||
{
|
|
||||||
var np = p.GetCustomAttribute<FalconSPPrarmNameAttribute>(true);
|
|
||||||
if (np != null && np is FalconSPPrarmNameAttribute na)
|
|
||||||
{
|
|
||||||
var name = na.Name;
|
|
||||||
return name.StartsWith(prefixChar) ? name : prefixChar + name;
|
|
||||||
}
|
|
||||||
return prefixChar + p.Name;
|
|
||||||
}
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// 忽略大小写获取类型的属性
|
|
||||||
/// </summary>
|
|
||||||
/// <param name="t">类型</param>
|
|
||||||
/// <param name="name">属性名称</param>
|
|
||||||
/// <returns>属性</returns>
|
|
||||||
private static PropertyInfo getProperty(Type t, string name)
|
|
||||||
{
|
|
||||||
foreach (var item in t.GetProperties())
|
|
||||||
{
|
|
||||||
if (item.Name.ToLower() == name.ToLower())
|
|
||||||
{
|
|
||||||
return item;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// 生成存储过程参数字符串
|
|
||||||
/// </summary>
|
|
||||||
/// <param name="type">参数类型</param>
|
|
||||||
/// <param name="data">参数对象</param>
|
|
||||||
/// <returns>一个参数字符串。比如@p2=@p4,@p1=@p3</returns>
|
|
||||||
//private static string getParamStr(Type type,object data) {
|
|
||||||
// var paras = getParams(type,data).ToArray();
|
|
||||||
// var result = " ";
|
|
||||||
// for(int i = 0;i < paras.Count();i++) {
|
|
||||||
// result += $"{paras[i].ParameterName}={{{i}}},";
|
|
||||||
// }
|
|
||||||
// return result.TrimEnd(',');
|
|
||||||
//}
|
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
314
src/Falcon.StoredProcedureRunner/RunnerBase.cs
Normal file
314
src/Falcon.StoredProcedureRunner/RunnerBase.cs
Normal file
|
@ -0,0 +1,314 @@
|
||||||
|
using Falcon.StoredProcedureRunner.Attributes;
|
||||||
|
using Microsoft.Data.SqlClient;
|
||||||
|
using Microsoft.EntityFrameworkCore;
|
||||||
|
using Oracle.ManagedDataAccess.Client;
|
||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.Data;
|
||||||
|
using System.Data.Common;
|
||||||
|
using System.Linq;
|
||||||
|
using System.Reflection;
|
||||||
|
using System.Text;
|
||||||
|
|
||||||
|
namespace Falcon.StoredProcedureRunner
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// 存储过程执行
|
||||||
|
/// </summary>
|
||||||
|
public abstract class RunnerBase : IRunner
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// 执行无返回值的存储过程
|
||||||
|
/// </summary>
|
||||||
|
/// <typeparam name="TPrarmType">参数类型</typeparam>
|
||||||
|
/// <param name="db">数据上下文</param>
|
||||||
|
/// <param name="data">参数数据</param>
|
||||||
|
public int Execute<TPrarmType>(DbContext db, TPrarmType data)
|
||||||
|
{
|
||||||
|
throw new NotSupportedException();
|
||||||
|
//var parms = getParams(db, typeof(TPrarmType), data).ToArray();
|
||||||
|
//var pName = getProcuderName<TPrarmType>();
|
||||||
|
//var conn = db.Database.GetDbConnection();
|
||||||
|
|
||||||
|
|
||||||
|
//var paramStr = getParamStr(typeof(TPrarmType), data);
|
||||||
|
//var str = $"exec {pName} {paramStr}";
|
||||||
|
//return db.Database.ExecuteSqlRaw(str, parms);
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 通过数据库上下文执行存储过程,并返回查询结果
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="db">数据库上下文</param>
|
||||||
|
/// <param name="prarmType">参数类型</param>
|
||||||
|
/// <param name="returnType">返回值类型</param>
|
||||||
|
/// <param name="data">存储过程参数</param>
|
||||||
|
/// <returns>查询结果枚举</returns>
|
||||||
|
public abstract IEnumerable<object> Run(DbContext db, Type prarmType, Type returnType, object data);
|
||||||
|
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 通过数据库上下文执行存储过程,并返回查询结果
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="db">数据库上下文</param>
|
||||||
|
/// <param name="prarmType">参数类型</param>
|
||||||
|
/// <param name="returnType">返回值类型</param>
|
||||||
|
/// <param name="data">存储过程参数</param>
|
||||||
|
/// <returns>查询结果枚举</returns>
|
||||||
|
protected virtual IEnumerable<object> RunByReader(DbContext db, Type prarmType, Type returnType, object data)
|
||||||
|
{
|
||||||
|
var pm = GetProcuderName(prarmType);
|
||||||
|
var paras = getParams( prarmType, data).ToArray();
|
||||||
|
var conn = GetDbConnection(db);
|
||||||
|
using var cmd = conn.CreateCommand();
|
||||||
|
cmd.CommandText = pm;
|
||||||
|
cmd.CommandType = CommandType.StoredProcedure;
|
||||||
|
cmd.Parameters.AddRange(paras);
|
||||||
|
conn.Open();
|
||||||
|
using var dr = cmd.ExecuteReader();
|
||||||
|
cmd.Parameters.Clear();
|
||||||
|
var columnSchema = dr.GetColumnSchema();
|
||||||
|
var result = new List<object>();
|
||||||
|
if (!dr.CanGetColumnSchema())
|
||||||
|
return result;
|
||||||
|
int rowId = 0;
|
||||||
|
while (dr.Read())
|
||||||
|
{
|
||||||
|
var item = returnType.Assembly.CreateInstance(returnType.FullName);
|
||||||
|
for (var i = 0; i < columnSchema.Count; i++)
|
||||||
|
{
|
||||||
|
var name = dr.GetName(i);
|
||||||
|
var value = dr.IsDBNull(i) ? null : dr.GetValue(i);
|
||||||
|
var pi = getProperty(returnType, name);
|
||||||
|
if (pi == null || !pi.CanWrite)
|
||||||
|
continue;
|
||||||
|
try
|
||||||
|
{
|
||||||
|
pi.SetValue(item, value);
|
||||||
|
}
|
||||||
|
catch (Exception ex)
|
||||||
|
{
|
||||||
|
throw new ReturnDataSetValueException(rowId, name, pi, value, ex);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
result.Add(item);
|
||||||
|
rowId++;
|
||||||
|
}
|
||||||
|
conn.Close();
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 获取数据库链接
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="context">数据库上下文</param>
|
||||||
|
/// <returns>数据链接</returns>
|
||||||
|
protected abstract DbConnection GetDbConnection(DbContext context);
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 将Dataset转换为IEnumerable
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="ds">数据集</param>
|
||||||
|
/// <param name="returnType">枚举元素类型</param>
|
||||||
|
/// <returns>枚举类型</returns>
|
||||||
|
/// <exception cref="ReturnDataSetValueException">数据赋值异常</exception>
|
||||||
|
public IEnumerable<object> DataSetToIEnumerable(DataSet ds, Type returnType)
|
||||||
|
{
|
||||||
|
var result = new List<object>();
|
||||||
|
var rows = ds.Tables[0].Rows;
|
||||||
|
var cols = ds.Tables[0].Columns;
|
||||||
|
for (int i = 0; i < rows.Count; i++)
|
||||||
|
{
|
||||||
|
var item = returnType.Assembly.CreateInstance(returnType.FullName);
|
||||||
|
var row = rows[i];
|
||||||
|
for (int y = 0; y < cols.Count; y++)
|
||||||
|
{
|
||||||
|
var name = cols[y].ColumnName;
|
||||||
|
var val = row[y] is DBNull ? null : row[y];
|
||||||
|
var pi = getProperty(returnType, name);
|
||||||
|
if (pi == null || !pi.CanWrite)
|
||||||
|
continue;
|
||||||
|
try
|
||||||
|
{
|
||||||
|
pi.SetValue(item, val);
|
||||||
|
}
|
||||||
|
catch (Exception ex)
|
||||||
|
{
|
||||||
|
throw new ReturnDataSetValueException(i, name, pi, val, ex);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
result.Add(item);
|
||||||
|
}
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// (存在sql注入风险)执行Sql语句,并将数据库返回结果以json数据对象返回。
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="db">数据上下文</param>
|
||||||
|
/// <param name="sql">要执行的sql语句</param>
|
||||||
|
/// <returns>数据库返回值json格式</returns>
|
||||||
|
public string RunRaw(DbContext db, string sql)
|
||||||
|
{
|
||||||
|
var connection = db.Database.GetDbConnection();
|
||||||
|
using var cmd = connection.CreateCommand();
|
||||||
|
cmd.CommandText = sql;
|
||||||
|
cmd.CommandType = System.Data.CommandType.Text;
|
||||||
|
connection.Open();
|
||||||
|
var dr = cmd.ExecuteReader();
|
||||||
|
var result = new StringBuilder();
|
||||||
|
if (!dr.CanGetColumnSchema())
|
||||||
|
return "";
|
||||||
|
while (dr.Read())
|
||||||
|
{
|
||||||
|
var item = new StringBuilder();
|
||||||
|
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);
|
||||||
|
item.Append($"\"{name}\":\"{value}\",");
|
||||||
|
}
|
||||||
|
result.Append($"{{{item.ToString().TrimEnd(',')}}},");
|
||||||
|
}
|
||||||
|
connection.Close();
|
||||||
|
return "[" + result.ToString().TrimEnd(',') + "]";
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 获取返回类型临时表名称
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="returnType">返回类型</param>
|
||||||
|
/// <returns></returns>
|
||||||
|
protected virtual string GetTempTableName(Type returnType)
|
||||||
|
{
|
||||||
|
var attr = returnType.GetCustomAttribute<FalconSPTempTableAttribute>();
|
||||||
|
return attr?.TableName ?? returnType.Name;
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 获取存储过程名
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="pramType">参数类型</param>
|
||||||
|
protected virtual string GetProcuderName(Type pramType)
|
||||||
|
{
|
||||||
|
var attr = pramType.GetCustomAttribute<FalconSPProcuderNameAttribute>();
|
||||||
|
return attr?.ProcuderName ?? pramType.Name;
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 获取存储过程参数枚举
|
||||||
|
/// </summary>
|
||||||
|
///<param name="type">数据的类型</param>
|
||||||
|
/// <param name="data">参数实例</param>
|
||||||
|
protected virtual IEnumerable<IDataParameter> getParams(Type type, object data)
|
||||||
|
{
|
||||||
|
if (data == null)
|
||||||
|
yield break;
|
||||||
|
var fixC = GetParamProfix();
|
||||||
|
foreach (var p in type.GetProperties())
|
||||||
|
{
|
||||||
|
if (!p.CanRead || IsIgnoreProp(p))
|
||||||
|
continue;
|
||||||
|
var name = GetPrarmName(p, fixC);
|
||||||
|
var val = p.GetValue(data);
|
||||||
|
var pt = getPrarmType(p);
|
||||||
|
var para = CreateDbParameter(name, val, pt.type, pt.size);
|
||||||
|
para.Direction = GetParaDirection(p);
|
||||||
|
yield return para;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 获取数据库参数前缀
|
||||||
|
/// </summary>
|
||||||
|
/// <returns>前缀字符串</returns>
|
||||||
|
protected abstract string GetParamProfix();
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 获取存储过程参数类型
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="p">对应的属性</param>
|
||||||
|
private (int? type, int? size) getPrarmType(PropertyInfo p)
|
||||||
|
{
|
||||||
|
var np = p.GetCustomAttribute<FalconSPPrarmTypeAttribute>();
|
||||||
|
if (np != null && np is FalconSPPrarmTypeAttribute na)
|
||||||
|
{
|
||||||
|
return ((int)np.PType, np.Size);
|
||||||
|
}
|
||||||
|
return (null, null);
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 创建存储过程参数
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="name">参数名称</param>
|
||||||
|
/// <param name="val">参数值</param>
|
||||||
|
/// <param name="type">存储过程参数数据库类型</param>
|
||||||
|
/// <param name="size">数据长度</param>
|
||||||
|
/// <returns>参数</returns>
|
||||||
|
protected abstract IDataParameter CreateDbParameter(string name, object val, int? type, int? size);
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 获取参数的方向。默认Input
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="p">参数映射属性</param>
|
||||||
|
/// <returns>方向或null</returns>
|
||||||
|
protected virtual ParameterDirection GetParaDirection(PropertyInfo p)
|
||||||
|
{
|
||||||
|
var attr = p.GetCustomAttribute<FalconSPPrarmDirectionAttribute>();
|
||||||
|
return attr == null ? ParameterDirection.Input : attr.Direction;
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 是否忽略属性
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="p">要检查的属性</param>
|
||||||
|
protected virtual bool IsIgnoreProp(PropertyInfo p)
|
||||||
|
{
|
||||||
|
return p.GetCustomAttribute<FalconSPIgnoreAttribute>(true) != null;
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 获取存储过程参数名称
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="p">对应的属性</param>
|
||||||
|
/// <param name="prefixChar">存储过程参数前缀</param>
|
||||||
|
protected virtual string GetPrarmName(PropertyInfo p, string prefixChar)
|
||||||
|
{
|
||||||
|
var np = p.GetCustomAttribute<FalconSPPrarmNameAttribute>(true);
|
||||||
|
if (np != null && np is FalconSPPrarmNameAttribute na)
|
||||||
|
{
|
||||||
|
var name = na.Name;
|
||||||
|
return name.StartsWith(prefixChar) ? name : prefixChar + name;
|
||||||
|
}
|
||||||
|
return prefixChar + p.Name;
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 忽略大小写获取类型的属性
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="t">类型</param>
|
||||||
|
/// <param name="name">属性名称</param>
|
||||||
|
/// <returns>属性</returns>
|
||||||
|
protected virtual PropertyInfo getProperty(Type t, string name)
|
||||||
|
{
|
||||||
|
foreach (var item in t.GetProperties())
|
||||||
|
{
|
||||||
|
if (item.Name.ToLower() == name.ToLower())
|
||||||
|
{
|
||||||
|
return item;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 表是否存在
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="db">数据库上下文</param>
|
||||||
|
/// <param name="tableName">表名称</param>
|
||||||
|
/// <returns>存在True,不存在False</returns>
|
||||||
|
protected abstract bool IsTableExists(DbContext db, string tableName);
|
||||||
|
}
|
||||||
|
}
|
90
src/Falcon.StoredProcedureRunner/SqlServerRunner.cs
Normal file
90
src/Falcon.StoredProcedureRunner/SqlServerRunner.cs
Normal file
|
@ -0,0 +1,90 @@
|
||||||
|
using Microsoft.Data.SqlClient;
|
||||||
|
using Microsoft.EntityFrameworkCore;
|
||||||
|
using Microsoft.Extensions.Options;
|
||||||
|
using Oracle.ManagedDataAccess.Client;
|
||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.Data;
|
||||||
|
using System.Data.Common;
|
||||||
|
using System.Linq;
|
||||||
|
|
||||||
|
namespace Falcon.StoredProcedureRunner
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// 面向SqlServer的执行器
|
||||||
|
/// </summary>
|
||||||
|
public class SqlServerRunner : RunnerBase, ISqlServerRunner
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// 执行参数
|
||||||
|
/// </summary>
|
||||||
|
public SqlServerRunnerOtions Options { get; set; }
|
||||||
|
/// <summary>
|
||||||
|
/// 通过提供构造选项构造Oracle执行器
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="option">选项</param>
|
||||||
|
public SqlServerRunner(IOptions<SqlServerRunnerOtions> option = null)
|
||||||
|
{
|
||||||
|
this.Options = option?.Value ?? new SqlServerRunnerOtions();
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 表是否存在
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="db">数据库上下文</param>
|
||||||
|
/// <param name="tableName">表名称</param>
|
||||||
|
/// <returns>存在True,不存在False</returns>
|
||||||
|
protected override bool IsTableExists(DbContext db, string tableName)
|
||||||
|
{
|
||||||
|
throw new System.NotImplementedException();
|
||||||
|
}
|
||||||
|
|
||||||
|
public override IEnumerable<object> Run(DbContext db, Type prarmType, Type returnType, object data)
|
||||||
|
{
|
||||||
|
return RunByReturn(db, prarmType, returnType, data);
|
||||||
|
}
|
||||||
|
|
||||||
|
protected IEnumerable<object> RunByReturn(DbContext db, Type prarmType, Type returnType, object data)
|
||||||
|
{
|
||||||
|
var pm = GetProcuderName(prarmType);
|
||||||
|
var paras = getParams(prarmType, data).ToArray();
|
||||||
|
DbConnection connection = db.Database.GetDbConnection();
|
||||||
|
DataSet ds = new();
|
||||||
|
var conn = db.Database.GetDbConnection() as SqlConnection;
|
||||||
|
using var cmd = conn.CreateCommand();
|
||||||
|
cmd.CommandType = CommandType.StoredProcedure;
|
||||||
|
cmd.CommandText = pm;
|
||||||
|
cmd.Parameters.AddRange(paras);
|
||||||
|
var da = new SqlDataAdapter(cmd);
|
||||||
|
da.Fill(ds);
|
||||||
|
cmd.Parameters.Clear();
|
||||||
|
return DataSetToIEnumerable(ds, returnType);
|
||||||
|
}
|
||||||
|
/// <summary>
|
||||||
|
/// 获取SqlServer数据库链接
|
||||||
|
/// </summary>
|
||||||
|
protected override DbConnection GetDbConnection(DbContext context)
|
||||||
|
{
|
||||||
|
return context.Database.GetDbConnection();
|
||||||
|
}
|
||||||
|
/// <summary>
|
||||||
|
/// 获取存储过程参数前缀
|
||||||
|
/// </summary>
|
||||||
|
/// <returns></returns>
|
||||||
|
protected override string GetParamProfix()
|
||||||
|
{
|
||||||
|
return "@";
|
||||||
|
}
|
||||||
|
|
||||||
|
protected override IDataParameter CreateDbParameter(string name, object val, int? type, int? size)
|
||||||
|
{
|
||||||
|
DbParameter par =
|
||||||
|
type.HasValue && size.HasValue ? new SqlParameter(name, (SqlDbType)type, size.Value) :
|
||||||
|
type.HasValue && !size.HasValue ? new SqlParameter(name, (SqlDbType)type) :
|
||||||
|
!type.HasValue && !size.HasValue ? new SqlParameter(name, val) :
|
||||||
|
null;
|
||||||
|
par.Value = val;
|
||||||
|
return par as IDataParameter;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
10
src/Falcon.StoredProcedureRunner/SqlServerRunnerOtions.cs
Normal file
10
src/Falcon.StoredProcedureRunner/SqlServerRunnerOtions.cs
Normal file
|
@ -0,0 +1,10 @@
|
||||||
|
namespace Falcon.StoredProcedureRunner
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// Sqlserver执行配置
|
||||||
|
/// </summary>
|
||||||
|
public class SqlServerRunnerOtions
|
||||||
|
{
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
|
@ -3,5 +3,11 @@
|
||||||
"ver": "",
|
"ver": "",
|
||||||
"oracle": "",
|
"oracle": "",
|
||||||
"sqlserver": ""
|
"sqlserver": ""
|
||||||
|
},
|
||||||
|
"OracleRunner": {
|
||||||
|
"ReturnModel": 2
|
||||||
|
},
|
||||||
|
"SqlRunner": {
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -13,6 +13,7 @@
|
||||||
<PackageReference Include="Microsoft.Extensions.Configuration" Version="5.0.0" />
|
<PackageReference Include="Microsoft.Extensions.Configuration" Version="5.0.0" />
|
||||||
<PackageReference Include="Microsoft.Extensions.Configuration.Json" Version="5.0.0" />
|
<PackageReference Include="Microsoft.Extensions.Configuration.Json" Version="5.0.0" />
|
||||||
<PackageReference Include="Microsoft.Extensions.Configuration.UserSecrets" Version="5.0.0" />
|
<PackageReference Include="Microsoft.Extensions.Configuration.UserSecrets" Version="5.0.0" />
|
||||||
|
<PackageReference Include="Microsoft.Extensions.Options.ConfigurationExtensions" Version="5.0.0" />
|
||||||
<PackageReference Include="Microsoft.NET.Test.Sdk" Version="16.11.0" />
|
<PackageReference Include="Microsoft.NET.Test.Sdk" Version="16.11.0" />
|
||||||
<PackageReference Include="MSTest.TestAdapter" Version="2.2.7" />
|
<PackageReference Include="MSTest.TestAdapter" Version="2.2.7" />
|
||||||
<PackageReference Include="MSTest.TestFramework" Version="2.2.7" />
|
<PackageReference Include="MSTest.TestFramework" Version="2.2.7" />
|
||||||
|
@ -35,4 +36,8 @@
|
||||||
</None>
|
</None>
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
|
|
||||||
|
<ItemGroup>
|
||||||
|
<Folder Include="Falcon\" />
|
||||||
|
</ItemGroup>
|
||||||
|
|
||||||
</Project>
|
</Project>
|
||||||
|
|
|
@ -1,4 +1,5 @@
|
||||||
using Falcon.StoredProcedureRunner;
|
using Falcon.StoredProcedureRunner;
|
||||||
|
using Falcon.StoredProcedureRunner.Attributes;
|
||||||
using System.Data;
|
using System.Data;
|
||||||
|
|
||||||
namespace Falcon.StoredProcedureRunnerTests
|
namespace Falcon.StoredProcedureRunnerTests
|
||||||
|
@ -24,27 +25,24 @@ namespace Falcon.StoredProcedureRunnerTests
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public class Tjjk_Tjgh
|
public class Tjjk_Tjgh
|
||||||
{
|
{
|
||||||
/// <summary>
|
|
||||||
/// 身份证号码
|
|
||||||
/// </summary>
|
|
||||||
public string v_sfz { get; set; }
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// 医疗机构代码
|
/// 医疗机构代码
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public string v_yljgdm { get; set; }
|
public string v_yljgdm { get; set; }
|
||||||
/// <summary>
|
/// <summary>
|
||||||
|
/// 身份证号码
|
||||||
|
/// </summary>
|
||||||
|
public string v_sfz { get; set; }
|
||||||
|
/// <summary>
|
||||||
/// 挂号日期 格式yyyyMMdd
|
/// 挂号日期 格式yyyyMMdd
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public string v_ghrq { get; set; }
|
public string v_ghrq { get; set; }
|
||||||
|
|
||||||
[FalconSPPrarmDirection(ParameterDirection.Output)]
|
|
||||||
[FalconSPPrarmType(FalconSPDbType.OracleRefCursor)]
|
|
||||||
public object v_data { get; set; }
|
|
||||||
|
|
||||||
}
|
}
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// 挂号查询结果
|
/// 挂号查询结果
|
||||||
/// </summary>
|
/// </summary>
|
||||||
|
[FalconSPTempTable("TT_Tjjk_Tjgh")]
|
||||||
public class Tjjk_TjghResult
|
public class Tjjk_TjghResult
|
||||||
{
|
{
|
||||||
/// <summary>
|
/// <summary>
|
||||||
|
|
|
@ -3,33 +3,53 @@ using Microsoft.EntityFrameworkCore;
|
||||||
using Microsoft.Extensions.Configuration;
|
using Microsoft.Extensions.Configuration;
|
||||||
using Microsoft.VisualStudio.TestTools.UnitTesting;
|
using Microsoft.VisualStudio.TestTools.UnitTesting;
|
||||||
using System.Linq;
|
using System.Linq;
|
||||||
|
using Microsoft.Extensions.DependencyInjection;
|
||||||
|
using Oracle.ManagedDataAccess.Client;
|
||||||
|
using System.Data;
|
||||||
|
using System.ComponentModel.DataAnnotations;
|
||||||
|
|
||||||
namespace Falcon.StoredProcedureRunner.Tests
|
namespace Falcon.StoredProcedureRunner.Tests
|
||||||
{
|
{
|
||||||
[TestClass()]
|
[TestClass()]
|
||||||
public class RunnerTests
|
public class RunnerTests
|
||||||
{
|
{
|
||||||
[TestMethod("通用测试")]
|
[TestMethod("Runner创建测试")]
|
||||||
public void RunTest()
|
public void RunTest()
|
||||||
{
|
{
|
||||||
OracleTest();
|
var config = GetConfiguration();
|
||||||
System.Console.WriteLine("---------------------");
|
var services = CreateServiceScope(config);
|
||||||
SqlserverTest();
|
System.Console.WriteLine("数据注入完成");
|
||||||
|
System.Console.WriteLine("sqlRunner开始测试");
|
||||||
|
var sqlRunner = GetSqlRunner(services);
|
||||||
|
Assert.IsNotNull(sqlRunner);
|
||||||
|
Assert.IsNotNull(sqlRunner as ISqlServerRunner);
|
||||||
|
Assert.IsNotNull(sqlRunner as SqlServerRunner);
|
||||||
|
var sRunner = sqlRunner as SqlServerRunner;
|
||||||
|
Assert.IsNotNull(sRunner.Options);
|
||||||
|
System.Console.WriteLine("OracleRunner开始测试");
|
||||||
|
var oracleRunner = GetOracleRunner(services);
|
||||||
|
Assert.IsNotNull(oracleRunner);
|
||||||
|
Assert.IsNotNull(oracleRunner as IOracleRunner);
|
||||||
|
Assert.IsNotNull(oracleRunner as OracleRunner);
|
||||||
|
var oRunner = oracleRunner as OracleRunner;
|
||||||
|
Assert.IsNotNull(oRunner.Options);
|
||||||
|
Assert.IsTrue(oRunner.Options.ReturnModel == ReturnModel.TempTable);
|
||||||
|
|
||||||
|
//OracleTest();
|
||||||
|
//System.Console.WriteLine("---------------------");
|
||||||
|
//SqlserverTest();
|
||||||
}
|
}
|
||||||
|
|
||||||
[TestMethod()]
|
|
||||||
|
[TestMethod("Sqlserver执行测试")]
|
||||||
public void SqlserverTest()
|
public void SqlserverTest()
|
||||||
{
|
{
|
||||||
System.Console.WriteLine("SqlserverTest start!");
|
var config = GetConfiguration();
|
||||||
var configurationBuilder = new ConfigurationBuilder();
|
var services = CreateServiceScope(config);
|
||||||
configurationBuilder.AddJsonFile("AppSettings.json");
|
var db = CreateSqlDbContext(config);
|
||||||
configurationBuilder.AddUserSecrets(this.GetType().Assembly);
|
Assert.IsNotNull(db);
|
||||||
var config = configurationBuilder.Build();
|
var runner = GetSqlRunner(services);
|
||||||
var sql = config.GetSection("db:sqlserver").Value;
|
Assert.IsNotNull(runner);
|
||||||
var buider = new DbContextOptionsBuilder();
|
|
||||||
var db = new DbContext(buider.UseSqlServer(sql).Options);
|
|
||||||
IRunner runner = new Runner();
|
|
||||||
|
|
||||||
var result = runner.Run<SqlserverModel, SqlserverModelResult>(db, new SqlserverModel
|
var result = runner.Run<SqlserverModel, SqlserverModelResult>(db, new SqlserverModel
|
||||||
{
|
{
|
||||||
p1 = 1,
|
p1 = 1,
|
||||||
|
@ -44,54 +64,21 @@ namespace Falcon.StoredProcedureRunner.Tests
|
||||||
System.Console.WriteLine("SqlserverTest over!");
|
System.Console.WriteLine("SqlserverTest over!");
|
||||||
}
|
}
|
||||||
|
|
||||||
[TestMethod()]
|
[TestMethod("Oracle执行测试")]
|
||||||
public void OracleTest()
|
public void OracleTest()
|
||||||
{
|
{
|
||||||
System.Console.WriteLine("OracleTest start!");
|
var config = GetConfiguration();
|
||||||
var configurationBuilder = new ConfigurationBuilder();
|
var services = CreateServiceScope(config);
|
||||||
configurationBuilder.AddJsonFile("AppSettings.json");
|
var db = CreateOracleDbContext(config);
|
||||||
configurationBuilder.AddUserSecrets(this.GetType().Assembly);
|
Assert.IsNotNull(db);
|
||||||
var config = configurationBuilder.Build();
|
var runner = GetOracleRunner(services);
|
||||||
var ora = config.GetSection("db:oracle").Value;
|
Assert.IsNotNull(runner);
|
||||||
var oraVer = config.GetSection("db:ver").Value;
|
|
||||||
var buider = new DbContextOptionsBuilder();
|
|
||||||
var db = new DbContext(buider.UseOracle(ora, o => o.UseOracleSQLCompatibility(oraVer)).Options);
|
|
||||||
|
|
||||||
IRunner runner = new Runner();
|
|
||||||
var result = runner.Run<GetEmployee, GetEmployeeResult>(db, new GetEmployee
|
|
||||||
{
|
|
||||||
v_orgaid = "50e3d44d-9ca2-4fbd-9d5d-d32339b1b113",
|
|
||||||
}).ToList();
|
|
||||||
Assert.IsNotNull(result);
|
|
||||||
System.Console.WriteLine("result ok");
|
|
||||||
CollectionAssert.AllItemsAreNotNull(result);
|
|
||||||
Assert.IsTrue(result.Count > 0);
|
|
||||||
System.Console.WriteLine($"result count {result.Count}");
|
|
||||||
System.Console.WriteLine("OracleTest over!");
|
|
||||||
}
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// 体检接口 挂号查询测试
|
|
||||||
/// </summary>
|
|
||||||
[TestMethod()]
|
|
||||||
public void Tjjk_TjghTest()
|
|
||||||
{
|
|
||||||
System.Console.WriteLine("OracleTest start!");
|
|
||||||
var configurationBuilder = new ConfigurationBuilder();
|
|
||||||
configurationBuilder.AddJsonFile("AppSettings.json");
|
|
||||||
configurationBuilder.AddUserSecrets(this.GetType().Assembly);
|
|
||||||
var config = configurationBuilder.Build();
|
|
||||||
var ora = config.GetSection("db:oracle").Value;
|
|
||||||
var oraVer = config.GetSection("db:ver").Value;
|
|
||||||
var buider = new DbContextOptionsBuilder();
|
|
||||||
var db = new DbContext(buider.UseOracle(ora, o => o.UseOracleSQLCompatibility(oraVer)).Options);
|
|
||||||
|
|
||||||
IRunner runner = new Runner();
|
|
||||||
var result = runner.Run<Tjjk_Tjgh, Tjjk_TjghResult>(db, new Tjjk_Tjgh
|
var result = runner.Run<Tjjk_Tjgh, Tjjk_TjghResult>(db, new Tjjk_Tjgh
|
||||||
{
|
{
|
||||||
|
v_yljgdm = "50e3d44d-9ca2-4fbd-9d5d-d32339b1b113",
|
||||||
v_ghrq = "20211105",
|
v_ghrq = "20211105",
|
||||||
v_sfz = "610528199002165174",
|
v_sfz = "610528199002165174",
|
||||||
v_yljgdm = "50e3d44d-9ca2-4fbd-9d5d-d32339b1b113",
|
|
||||||
}).ToList();
|
}).ToList();
|
||||||
Assert.IsNotNull(result);
|
Assert.IsNotNull(result);
|
||||||
System.Console.WriteLine("result ok");
|
System.Console.WriteLine("result ok");
|
||||||
|
@ -101,31 +88,142 @@ namespace Falcon.StoredProcedureRunner.Tests
|
||||||
System.Console.WriteLine("OracleTest over!");
|
System.Console.WriteLine("OracleTest over!");
|
||||||
}
|
}
|
||||||
|
|
||||||
[TestMethod()]
|
[TestMethod("Oracle原始执行执行测试")]
|
||||||
public void GetDoctorDataTest()
|
public void OracleRawTest()
|
||||||
|
{
|
||||||
|
var config = GetConfiguration();
|
||||||
|
var services = CreateServiceScope(config);
|
||||||
|
var db = CreateOracleDbContext(config);
|
||||||
|
Assert.IsNotNull(db);
|
||||||
|
var cmd = db.Database.GetDbConnection().CreateCommand() as OracleCommand;
|
||||||
|
cmd.CommandType = CommandType.StoredProcedure;
|
||||||
|
cmd.CommandText = "Tjjk_Tjgh";
|
||||||
|
var a = new OracleParameter(":v_yljgdm", OracleDbType.Char, 36)
|
||||||
|
{
|
||||||
|
Value = "50e3d44d-9ca2-4fbd-9d5d-d32339b1b113"
|
||||||
|
};
|
||||||
|
cmd.Parameters.Add(a);
|
||||||
|
|
||||||
|
var c = new OracleParameter(":v_sfz", OracleDbType.Varchar2, 36);
|
||||||
|
c.Value = "610528199002165174";
|
||||||
|
cmd.Parameters.Add(c);
|
||||||
|
|
||||||
|
var b = new OracleParameter(":v_ghrq", OracleDbType.Char, 8);
|
||||||
|
b.Value = "20211105";
|
||||||
|
cmd.Parameters.Add(b);
|
||||||
|
db.Database.GetDbConnection().Open();
|
||||||
|
cmd.ExecuteNonQuery();
|
||||||
|
cmd.CommandText = "select * from tt_tjjk_tjgh";
|
||||||
|
cmd.CommandType = CommandType.Text;
|
||||||
|
var da = new OracleDataAdapter(cmd);
|
||||||
|
DataSet ds = new();
|
||||||
|
da.Fill(ds);
|
||||||
|
System.Console.WriteLine(ds.Tables[0].Rows.Count);
|
||||||
|
}
|
||||||
|
|
||||||
|
public DbContext CreateSqlDbContext(IConfiguration config)
|
||||||
|
{
|
||||||
|
var ora = config.GetSection("db:sqlserver").Value;
|
||||||
|
var buider = new DbContextOptionsBuilder();
|
||||||
|
return new DbContext(buider.UseSqlServer(ora).Options);
|
||||||
|
}
|
||||||
|
|
||||||
|
public DbContext CreateOracleDbContext(IConfiguration config)
|
||||||
{
|
{
|
||||||
System.Console.WriteLine("OracleTest start!");
|
|
||||||
var configurationBuilder = new ConfigurationBuilder();
|
|
||||||
configurationBuilder.AddJsonFile("AppSettings.json");
|
|
||||||
configurationBuilder.AddUserSecrets(this.GetType().Assembly);
|
|
||||||
var config = configurationBuilder.Build();
|
|
||||||
var ora = config.GetSection("db:oracle").Value;
|
var ora = config.GetSection("db:oracle").Value;
|
||||||
var oraVer = config.GetSection("db:ver").Value;
|
var oraVer = config.GetSection("db:ver").Value;
|
||||||
var buider = new DbContextOptionsBuilder();
|
var buider = new DbContextOptionsBuilder();
|
||||||
var db = new DbContext(buider.UseOracle(ora, o => o.UseOracleSQLCompatibility(oraVer)).Options);
|
return new DbContext(buider.UseOracle(ora, o => o.UseOracleSQLCompatibility(oraVer)).Options);
|
||||||
|
|
||||||
IRunner runner = new Runner();
|
|
||||||
var result = runner.Run<GetDoctorData, GetDoctorDataResult>(db, new GetDoctorData
|
|
||||||
{
|
|
||||||
v_orgaid = "50e3d44d-9ca2-4fbd-9d5d-d32339b1b113",
|
|
||||||
}).ToList();
|
|
||||||
Assert.IsNotNull(result);
|
|
||||||
System.Console.WriteLine("result ok");
|
|
||||||
CollectionAssert.AllItemsAreNotNull(result);
|
|
||||||
Assert.IsTrue(result.Count > 0);
|
|
||||||
System.Console.WriteLine($"result count {result.Count}");
|
|
||||||
System.Console.WriteLine("OracleTest over!");
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
///// <summary>
|
||||||
|
///// 体检接口 挂号查询测试
|
||||||
|
///// </summary>
|
||||||
|
//[TestMethod()]
|
||||||
|
//public void Tjjk_TjghTest()
|
||||||
|
//{
|
||||||
|
// System.Console.WriteLine("OracleTest start!");
|
||||||
|
// var configurationBuilder = new ConfigurationBuilder();
|
||||||
|
// configurationBuilder.AddJsonFile("AppSettings.json");
|
||||||
|
// configurationBuilder.AddUserSecrets(this.GetType().Assembly);
|
||||||
|
// var config = configurationBuilder.Build();
|
||||||
|
// var ora = config.GetSection("db:oracle").Value;
|
||||||
|
// var oraVer = config.GetSection("db:ver").Value;
|
||||||
|
// var buider = new DbContextOptionsBuilder();
|
||||||
|
// var db = new DbContext(buider.UseOracle(ora, o => o.UseOracleSQLCompatibility(oraVer)).Options);
|
||||||
|
|
||||||
|
// IRunner runner = new Runner();
|
||||||
|
// var result = runner.Run<Tjjk_Tjgh, Tjjk_TjghResult>(db, new Tjjk_Tjgh
|
||||||
|
// {
|
||||||
|
// v_ghrq = "20211105",
|
||||||
|
// v_sfz = "610528199002165174",
|
||||||
|
// v_yljgdm = "50e3d44d-9ca2-4fbd-9d5d-d32339b1b113",
|
||||||
|
// }).ToList();
|
||||||
|
// Assert.IsNotNull(result);
|
||||||
|
// System.Console.WriteLine("result ok");
|
||||||
|
// CollectionAssert.AllItemsAreNotNull(result);
|
||||||
|
// Assert.IsTrue(result.Count > 0);
|
||||||
|
// System.Console.WriteLine($"result count {result.Count}");
|
||||||
|
// System.Console.WriteLine("OracleTest over!");
|
||||||
|
//}
|
||||||
|
|
||||||
|
//[TestMethod()]
|
||||||
|
//public void GetDoctorDataTest()
|
||||||
|
//{
|
||||||
|
// System.Console.WriteLine("OracleTest start!");
|
||||||
|
// var configurationBuilder = new ConfigurationBuilder();
|
||||||
|
// configurationBuilder.AddJsonFile("AppSettings.json");
|
||||||
|
// configurationBuilder.AddUserSecrets(this.GetType().Assembly);
|
||||||
|
// var config = configurationBuilder.Build();
|
||||||
|
// var ora = config.GetSection("db:oracle").Value;
|
||||||
|
// var oraVer = config.GetSection("db:ver").Value;
|
||||||
|
// var buider = new DbContextOptionsBuilder();
|
||||||
|
// var db = new DbContext(buider.UseOracle(ora, o => o.UseOracleSQLCompatibility(oraVer)).Options);
|
||||||
|
|
||||||
|
// IRunner runner = new Runner();
|
||||||
|
// var result = runner.Run<GetDoctorData, GetDoctorDataResult>(db, new GetDoctorData
|
||||||
|
// {
|
||||||
|
// v_orgaid = "50e3d44d-9ca2-4fbd-9d5d-d32339b1b113",
|
||||||
|
// }).ToList();
|
||||||
|
// Assert.IsNotNull(result);
|
||||||
|
// System.Console.WriteLine("result ok");
|
||||||
|
// CollectionAssert.AllItemsAreNotNull(result);
|
||||||
|
// Assert.IsTrue(result.Count > 0);
|
||||||
|
// System.Console.WriteLine($"result count {result.Count}");
|
||||||
|
// System.Console.WriteLine("OracleTest over!");
|
||||||
|
//}
|
||||||
|
|
||||||
|
public static IConfiguration GetConfiguration()
|
||||||
|
{
|
||||||
|
var configurationBuilder = new ConfigurationBuilder();
|
||||||
|
configurationBuilder.AddJsonFile("AppSettings.json");
|
||||||
|
configurationBuilder.AddUserSecrets(typeof(RunnerTests).Assembly);
|
||||||
|
return configurationBuilder.Build();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
private IServiceScope CreateServiceScope(IConfiguration config)
|
||||||
|
{
|
||||||
|
IServiceCollection services = new ServiceCollection();
|
||||||
|
AddOptions(config, services);
|
||||||
|
services.AddFalconSPRunner();
|
||||||
|
return services.BuildServiceProvider().CreateScope();
|
||||||
|
}
|
||||||
|
|
||||||
|
public static void AddOptions(IConfiguration config, IServiceCollection services)
|
||||||
|
{
|
||||||
|
services.Configure<OracleRunnerOptions>(config.GetSection("OracleRunner"));
|
||||||
|
services.Configure<SqlServerRunnerOtions>(config.GetSection("SqlRunner"));
|
||||||
|
}
|
||||||
|
|
||||||
|
public static IRunner? GetSqlRunner(IServiceScope services)
|
||||||
|
{
|
||||||
|
return services.ServiceProvider.GetService<ISqlServerRunner>() as IRunner;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static IRunner? GetOracleRunner(IServiceScope services)
|
||||||
|
{
|
||||||
|
return services.ServiceProvider.GetService<IOracleRunner>() as IRunner;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
|
@ -1,12 +1,8 @@
|
||||||
using System;
|
using Falcon.StoredProcedureRunner.Attributes;
|
||||||
using System.Collections.Generic;
|
|
||||||
using System.Linq;
|
|
||||||
using System.Text;
|
|
||||||
using System.Threading.Tasks;
|
|
||||||
|
|
||||||
namespace Falcon.StoredProcedureRunnerTests
|
namespace Falcon.StoredProcedureRunnerTests
|
||||||
{
|
{
|
||||||
[Falcon.StoredProcedureRunner.FalconSPProcuderName("TestSp1")]
|
[FalconSPProcuderName("TestSp1")]
|
||||||
public class SqlserverModel
|
public class SqlserverModel
|
||||||
{
|
{
|
||||||
public int p1 { get; set; }
|
public int p1 { get; set; }
|
||||||
|
|
Loading…
Reference in New Issue
Block a user