mirror of
				https://github.com/FalconWu2017/Falcon.StoredProcedureRunner.git
				synced 2025-11-04 06:14:29 +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