mirror of
				https://github.com/FalconWu2017/Falcon.StoredProcedureRunner.git
				synced 2025-10-30 02:24:27 +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…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user