mirror of
				https://github.com/nsnail/FreeSql.git
				synced 2025-11-04 09:15:27 +08:00 
			
		
		
		
	arrange
This commit is contained in:
		
							
								
								
									
										10
									
								
								Examples/FreeSql.RESTful.Demo/Entity/Song.cs
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										10
									
								
								Examples/FreeSql.RESTful.Demo/Entity/Song.cs
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,10 @@
 | 
			
		||||
using FreeSql.DataAnnotations;
 | 
			
		||||
 | 
			
		||||
namespace FreeSql.RESTful.Demo.Entity {
 | 
			
		||||
	public class Song {
 | 
			
		||||
 | 
			
		||||
		[Column(IsIdentity = true)]
 | 
			
		||||
		public int Id { get; set; }
 | 
			
		||||
		public string Title { get; set; }
 | 
			
		||||
	}
 | 
			
		||||
}
 | 
			
		||||
@@ -7,15 +7,14 @@
 | 
			
		||||
 | 
			
		||||
	<ItemGroup>
 | 
			
		||||
		<PackageReference Include="Microsoft.AspNetCore.App" />
 | 
			
		||||
		<PackageReference Include="Microsoft.EntityFrameworkCore" Version="2.1.8" />
 | 
			
		||||
		<PackageReference Include="Microsoft.EntityFrameworkCore.Sqlite" Version="2.1.8" />
 | 
			
		||||
		<PackageReference Include="Swashbuckle.AspNetCore" Version="4.0.1" />
 | 
			
		||||
		<PackageReference Include="Swashbuckle.AspNetCore.Annotations" Version="4.0.1" />
 | 
			
		||||
		<PackageReference Include="System.Text.Encoding.CodePages" Version="4.5.1" />
 | 
			
		||||
	</ItemGroup>
 | 
			
		||||
 | 
			
		||||
	<ItemGroup>
 | 
			
		||||
	  <ProjectReference Include="..\FreeSql\FreeSql.csproj" />
 | 
			
		||||
	  <ProjectReference Include="..\..\FreeSql.Extensions.EFCoreModelBuilder\FreeSql.Extensions.EFCoreModelBuilder.csproj" />
 | 
			
		||||
	  <ProjectReference Include="..\..\FreeSql\FreeSql.csproj" />
 | 
			
		||||
	</ItemGroup>
 | 
			
		||||
 | 
			
		||||
</Project>
 | 
			
		||||
							
								
								
									
										27
									
								
								Examples/FreeSql.RESTful.Demo/Properties/launchSettings.json
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										27
									
								
								Examples/FreeSql.RESTful.Demo/Properties/launchSettings.json
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,27 @@
 | 
			
		||||
{
 | 
			
		||||
  "iisSettings": {
 | 
			
		||||
    "windowsAuthentication": false,
 | 
			
		||||
    "anonymousAuthentication": true,
 | 
			
		||||
    "iisExpress": {
 | 
			
		||||
      "applicationUrl": "http://localhost:49778/",
 | 
			
		||||
      "sslPort": 0
 | 
			
		||||
    }
 | 
			
		||||
  },
 | 
			
		||||
  "profiles": {
 | 
			
		||||
    "IIS Express": {
 | 
			
		||||
      "commandName": "IISExpress",
 | 
			
		||||
      "launchBrowser": true,
 | 
			
		||||
      "environmentVariables": {
 | 
			
		||||
        "ASPNETCORE_ENVIRONMENT": "Development"
 | 
			
		||||
      }
 | 
			
		||||
    },
 | 
			
		||||
    "FreeSql.RESTful.Demo": {
 | 
			
		||||
      "commandName": "Project",
 | 
			
		||||
      "launchBrowser": true,
 | 
			
		||||
      "environmentVariables": {
 | 
			
		||||
        "ASPNETCORE_ENVIRONMENT": "Development"
 | 
			
		||||
      },
 | 
			
		||||
      "applicationUrl": "http://localhost:49779/"
 | 
			
		||||
    }
 | 
			
		||||
  }
 | 
			
		||||
}
 | 
			
		||||
@@ -1,22 +1,14 @@
 | 
			
		||||
using System;
 | 
			
		||||
using System.Collections.Generic;
 | 
			
		||||
using System.Linq;
 | 
			
		||||
using System.Text;
 | 
			
		||||
using System.Threading.Tasks;
 | 
			
		||||
using Microsoft.AspNetCore.Builder;
 | 
			
		||||
using Microsoft.AspNetCore.Builder;
 | 
			
		||||
using Microsoft.AspNetCore.Hosting;
 | 
			
		||||
using Microsoft.AspNetCore.HttpsPolicy;
 | 
			
		||||
using Microsoft.AspNetCore.Mvc;
 | 
			
		||||
using Microsoft.EntityFrameworkCore.Metadata.Builders;
 | 
			
		||||
using Microsoft.Extensions.Configuration;
 | 
			
		||||
using Microsoft.Extensions.DependencyInjection;
 | 
			
		||||
using Microsoft.Extensions.Logging;
 | 
			
		||||
using Microsoft.Extensions.Options;
 | 
			
		||||
using Swashbuckle.AspNetCore.Swagger;
 | 
			
		||||
using System;
 | 
			
		||||
using System.Text;
 | 
			
		||||
 | 
			
		||||
namespace FreeSql.RESTful.Demo
 | 
			
		||||
{
 | 
			
		||||
    public class Startup
 | 
			
		||||
namespace FreeSql.RESTful.Demo {
 | 
			
		||||
	public class Startup
 | 
			
		||||
    {
 | 
			
		||||
        public Startup(IConfiguration configuration, ILoggerFactory loggerFactory)
 | 
			
		||||
        {
 | 
			
		||||
@@ -1,64 +1,67 @@
 | 
			
		||||
using Microsoft.EntityFrameworkCore;
 | 
			
		||||
using FreeSql;
 | 
			
		||||
using Microsoft.EntityFrameworkCore;
 | 
			
		||||
using Microsoft.EntityFrameworkCore.Metadata;
 | 
			
		||||
using System;
 | 
			
		||||
using System.Linq;
 | 
			
		||||
 | 
			
		||||
namespace FreeSql.Extensions.EFCoreModelBuilder {
 | 
			
		||||
public static class FreeSqlExtensionsEFCoreModelBuilderCodeFirstExtensions {
 | 
			
		||||
 | 
			
		||||
	public static class CodeFirstExtensions {
 | 
			
		||||
public static void ConfigEntity(this ICodeFirst codeFirst, IModel efmodel) {
 | 
			
		||||
 | 
			
		||||
		public static void ConfigEntity(this ICodeFirst codeFirst, ModelBuilder modelBuilder) {
 | 
			
		||||
	foreach (var type in efmodel.GetEntityTypes()) {
 | 
			
		||||
 | 
			
		||||
			foreach (var type in modelBuilder.Model.GetEntityTypes()) {
 | 
			
		||||
		codeFirst.ConfigEntity(type.ClrType, a => {
 | 
			
		||||
 | 
			
		||||
				codeFirst.ConfigEntity(type.ClrType, a => {
 | 
			
		||||
 | 
			
		||||
					//表名
 | 
			
		||||
					var relationalTableName = type.FindAnnotation("Relational:TableName");
 | 
			
		||||
					if (relationalTableName != null) {
 | 
			
		||||
						a.Name(relationalTableName.Value?.ToString() ?? type.ClrType.Name);
 | 
			
		||||
					}
 | 
			
		||||
 | 
			
		||||
					foreach (var prop in type.GetProperties()) {
 | 
			
		||||
 | 
			
		||||
						var freeProp = a.Property(prop.Name);
 | 
			
		||||
 | 
			
		||||
						//列名
 | 
			
		||||
						var relationalColumnName = prop.FindAnnotation("Relational:ColumnName");
 | 
			
		||||
						if (relationalColumnName != null) {
 | 
			
		||||
 | 
			
		||||
							freeProp.Name(relationalColumnName.Value?.ToString() ?? prop.Name);
 | 
			
		||||
						}
 | 
			
		||||
 | 
			
		||||
						//主键
 | 
			
		||||
						freeProp.IsPrimary(prop.IsPrimaryKey());
 | 
			
		||||
 | 
			
		||||
						//自增
 | 
			
		||||
						freeProp.IsIdentity(prop.GetAnnotations().Where(z => 
 | 
			
		||||
							z.Name == "SqlServer:ValueGenerationStrategy" && z.Value.ToString().Contains("IdentityColumn") //sqlserver 自增
 | 
			
		||||
							|| z.Value.ToString().Contains("IdentityColumn") //其他数据库实现未经测试
 | 
			
		||||
						).Any());
 | 
			
		||||
 | 
			
		||||
						//可空
 | 
			
		||||
						freeProp.IsNullable(prop.AfterSaveBehavior != Microsoft.EntityFrameworkCore.Metadata.PropertySaveBehavior.Throw);
 | 
			
		||||
 | 
			
		||||
						//类型
 | 
			
		||||
						var relationalColumnType = prop.FindAnnotation("Relational:ColumnType");
 | 
			
		||||
						if (relationalColumnType != null) {
 | 
			
		||||
 | 
			
		||||
							var dbType = relationalColumnType.ToString();
 | 
			
		||||
 | 
			
		||||
							if (!string.IsNullOrEmpty(dbType)) {
 | 
			
		||||
 | 
			
		||||
								var maxLength = prop.FindAnnotation("MaxLength");
 | 
			
		||||
								if (maxLength != null)
 | 
			
		||||
									dbType += $"({maxLength})";
 | 
			
		||||
 | 
			
		||||
								freeProp.DbType(dbType);
 | 
			
		||||
							}
 | 
			
		||||
						}
 | 
			
		||||
					}
 | 
			
		||||
				});
 | 
			
		||||
			//表名
 | 
			
		||||
			var relationalTableName = type.FindAnnotation("Relational:TableName");
 | 
			
		||||
			if (relationalTableName != null) {
 | 
			
		||||
				a.Name(relationalTableName.Value?.ToString() ?? type.ClrType.Name);
 | 
			
		||||
			}
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
			foreach (var prop in type.GetProperties()) {
 | 
			
		||||
 | 
			
		||||
				var freeProp = a.Property(prop.Name);
 | 
			
		||||
 | 
			
		||||
				//列名
 | 
			
		||||
				var relationalColumnName = prop.FindAnnotation("Relational:ColumnName");
 | 
			
		||||
				if (relationalColumnName != null) {
 | 
			
		||||
 | 
			
		||||
					freeProp.Name(relationalColumnName.Value?.ToString() ?? prop.Name);
 | 
			
		||||
				}
 | 
			
		||||
 | 
			
		||||
				//主键
 | 
			
		||||
				freeProp.IsPrimary(prop.IsPrimaryKey());
 | 
			
		||||
 | 
			
		||||
				//自增
 | 
			
		||||
				freeProp.IsIdentity(
 | 
			
		||||
					prop.ValueGenerated == ValueGenerated.Never ||
 | 
			
		||||
					prop.ValueGenerated == ValueGenerated.OnAdd ||
 | 
			
		||||
					prop.GetAnnotations().Where(z =>
 | 
			
		||||
						z.Name == "SqlServer:ValueGenerationStrategy" && z.Value.ToString().Contains("IdentityColumn") //sqlserver 自增
 | 
			
		||||
						|| z.Value.ToString().Contains("IdentityColumn") //其他数据库实现未经测试
 | 
			
		||||
					).Any()
 | 
			
		||||
				);
 | 
			
		||||
 | 
			
		||||
				//可空
 | 
			
		||||
				freeProp.IsNullable(prop.AfterSaveBehavior != PropertySaveBehavior.Throw);
 | 
			
		||||
 | 
			
		||||
				//类型
 | 
			
		||||
				var relationalColumnType = prop.FindAnnotation("Relational:ColumnType");
 | 
			
		||||
				if (relationalColumnType != null) {
 | 
			
		||||
 | 
			
		||||
					var dbType = relationalColumnType.ToString();
 | 
			
		||||
 | 
			
		||||
					if (!string.IsNullOrEmpty(dbType)) {
 | 
			
		||||
 | 
			
		||||
						var maxLength = prop.FindAnnotation("MaxLength");
 | 
			
		||||
						if (maxLength != null)
 | 
			
		||||
							dbType += $"({maxLength})";
 | 
			
		||||
 | 
			
		||||
						freeProp.DbType(dbType);
 | 
			
		||||
					}
 | 
			
		||||
				}
 | 
			
		||||
			}
 | 
			
		||||
		});
 | 
			
		||||
	}
 | 
			
		||||
}
 | 
			
		||||
}
 | 
			
		||||
@@ -1,15 +0,0 @@
 | 
			
		||||
using Microsoft.EntityFrameworkCore;
 | 
			
		||||
using System;
 | 
			
		||||
using System.Collections.Generic;
 | 
			
		||||
using System.ComponentModel.DataAnnotations;
 | 
			
		||||
using System.ComponentModel.DataAnnotations.Schema;
 | 
			
		||||
using System.Linq;
 | 
			
		||||
using System.Threading.Tasks;
 | 
			
		||||
 | 
			
		||||
namespace FreeSql.RESTful.Demo.Entity {
 | 
			
		||||
	public class Song {
 | 
			
		||||
 | 
			
		||||
		public int Id { get; set; }
 | 
			
		||||
		public string Title { get; set; }
 | 
			
		||||
	}
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										47
									
								
								FreeSql.sln
									
									
									
									
									
								
							
							
						
						
									
										47
									
								
								FreeSql.sln
									
									
									
									
									
								
							@@ -12,14 +12,14 @@ Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Docs", "Docs", "{C6A74E2A-6
 | 
			
		||||
		readme.md = readme.md
 | 
			
		||||
	EndProjectSection
 | 
			
		||||
EndProject
 | 
			
		||||
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "xxx", "..\..\新建文件夹 (9)\xxx.csproj", "{6DC39740-0B26-4029-AB75-D436A7F666A2}"
 | 
			
		||||
EndProject
 | 
			
		||||
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "FreeSql.Tests.PerformanceTests", "FreeSql.Tests.PerformanceTests\FreeSql.Tests.PerformanceTests.csproj", "{446D9CBE-BFE4-4FB3-ADFD-4C1C5EA1B6EE}"
 | 
			
		||||
EndProject
 | 
			
		||||
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "FreeSql.RESTful.Demo", "FreeSql.RESTful.Demo\FreeSql.RESTful.Demo.csproj", "{A749092B-4C21-4087-B33D-0FBD4DA51C24}"
 | 
			
		||||
EndProject
 | 
			
		||||
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "FreeSql.Extensions.EFCoreModelBuilder", "FreeSql.Extensions.EFCoreModelBuilder\FreeSql.Extensions.EFCoreModelBuilder.csproj", "{490CC8AF-C47C-4139-AED7-4FB6502F622B}"
 | 
			
		||||
EndProject
 | 
			
		||||
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Examples", "Examples", "{94C8A78D-AA15-47B2-A348-530CD86BFC1B}"
 | 
			
		||||
EndProject
 | 
			
		||||
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "FreeSql.RESTful.Demo", "Examples\FreeSql.RESTful.Demo\FreeSql.RESTful.Demo.csproj", "{C32C7D4A-76D2-4A43-9A41-4B0440819954}"
 | 
			
		||||
EndProject
 | 
			
		||||
Global
 | 
			
		||||
	GlobalSection(SolutionConfigurationPlatforms) = preSolution
 | 
			
		||||
		Debug|Any CPU = Debug|Any CPU
 | 
			
		||||
@@ -54,18 +54,6 @@ Global
 | 
			
		||||
		{AA88EB04-4788-4180-AE68-7FA5ED17D98C}.Release|x64.Build.0 = Release|Any CPU
 | 
			
		||||
		{AA88EB04-4788-4180-AE68-7FA5ED17D98C}.Release|x86.ActiveCfg = Release|Any CPU
 | 
			
		||||
		{AA88EB04-4788-4180-AE68-7FA5ED17D98C}.Release|x86.Build.0 = Release|Any CPU
 | 
			
		||||
		{6DC39740-0B26-4029-AB75-D436A7F666A2}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
 | 
			
		||||
		{6DC39740-0B26-4029-AB75-D436A7F666A2}.Debug|Any CPU.Build.0 = Debug|Any CPU
 | 
			
		||||
		{6DC39740-0B26-4029-AB75-D436A7F666A2}.Debug|x64.ActiveCfg = Debug|Any CPU
 | 
			
		||||
		{6DC39740-0B26-4029-AB75-D436A7F666A2}.Debug|x64.Build.0 = Debug|Any CPU
 | 
			
		||||
		{6DC39740-0B26-4029-AB75-D436A7F666A2}.Debug|x86.ActiveCfg = Debug|Any CPU
 | 
			
		||||
		{6DC39740-0B26-4029-AB75-D436A7F666A2}.Debug|x86.Build.0 = Debug|Any CPU
 | 
			
		||||
		{6DC39740-0B26-4029-AB75-D436A7F666A2}.Release|Any CPU.ActiveCfg = Release|Any CPU
 | 
			
		||||
		{6DC39740-0B26-4029-AB75-D436A7F666A2}.Release|Any CPU.Build.0 = Release|Any CPU
 | 
			
		||||
		{6DC39740-0B26-4029-AB75-D436A7F666A2}.Release|x64.ActiveCfg = Release|Any CPU
 | 
			
		||||
		{6DC39740-0B26-4029-AB75-D436A7F666A2}.Release|x64.Build.0 = Release|Any CPU
 | 
			
		||||
		{6DC39740-0B26-4029-AB75-D436A7F666A2}.Release|x86.ActiveCfg = Release|Any CPU
 | 
			
		||||
		{6DC39740-0B26-4029-AB75-D436A7F666A2}.Release|x86.Build.0 = Release|Any CPU
 | 
			
		||||
		{446D9CBE-BFE4-4FB3-ADFD-4C1C5EA1B6EE}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
 | 
			
		||||
		{446D9CBE-BFE4-4FB3-ADFD-4C1C5EA1B6EE}.Debug|Any CPU.Build.0 = Debug|Any CPU
 | 
			
		||||
		{446D9CBE-BFE4-4FB3-ADFD-4C1C5EA1B6EE}.Debug|x64.ActiveCfg = Debug|Any CPU
 | 
			
		||||
@@ -78,18 +66,6 @@ Global
 | 
			
		||||
		{446D9CBE-BFE4-4FB3-ADFD-4C1C5EA1B6EE}.Release|x64.Build.0 = Release|Any CPU
 | 
			
		||||
		{446D9CBE-BFE4-4FB3-ADFD-4C1C5EA1B6EE}.Release|x86.ActiveCfg = Release|Any CPU
 | 
			
		||||
		{446D9CBE-BFE4-4FB3-ADFD-4C1C5EA1B6EE}.Release|x86.Build.0 = Release|Any CPU
 | 
			
		||||
		{A749092B-4C21-4087-B33D-0FBD4DA51C24}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
 | 
			
		||||
		{A749092B-4C21-4087-B33D-0FBD4DA51C24}.Debug|Any CPU.Build.0 = Debug|Any CPU
 | 
			
		||||
		{A749092B-4C21-4087-B33D-0FBD4DA51C24}.Debug|x64.ActiveCfg = Debug|Any CPU
 | 
			
		||||
		{A749092B-4C21-4087-B33D-0FBD4DA51C24}.Debug|x64.Build.0 = Debug|Any CPU
 | 
			
		||||
		{A749092B-4C21-4087-B33D-0FBD4DA51C24}.Debug|x86.ActiveCfg = Debug|Any CPU
 | 
			
		||||
		{A749092B-4C21-4087-B33D-0FBD4DA51C24}.Debug|x86.Build.0 = Debug|Any CPU
 | 
			
		||||
		{A749092B-4C21-4087-B33D-0FBD4DA51C24}.Release|Any CPU.ActiveCfg = Release|Any CPU
 | 
			
		||||
		{A749092B-4C21-4087-B33D-0FBD4DA51C24}.Release|Any CPU.Build.0 = Release|Any CPU
 | 
			
		||||
		{A749092B-4C21-4087-B33D-0FBD4DA51C24}.Release|x64.ActiveCfg = Release|Any CPU
 | 
			
		||||
		{A749092B-4C21-4087-B33D-0FBD4DA51C24}.Release|x64.Build.0 = Release|Any CPU
 | 
			
		||||
		{A749092B-4C21-4087-B33D-0FBD4DA51C24}.Release|x86.ActiveCfg = Release|Any CPU
 | 
			
		||||
		{A749092B-4C21-4087-B33D-0FBD4DA51C24}.Release|x86.Build.0 = Release|Any CPU
 | 
			
		||||
		{490CC8AF-C47C-4139-AED7-4FB6502F622B}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
 | 
			
		||||
		{490CC8AF-C47C-4139-AED7-4FB6502F622B}.Debug|Any CPU.Build.0 = Debug|Any CPU
 | 
			
		||||
		{490CC8AF-C47C-4139-AED7-4FB6502F622B}.Debug|x64.ActiveCfg = Debug|Any CPU
 | 
			
		||||
@@ -102,10 +78,25 @@ Global
 | 
			
		||||
		{490CC8AF-C47C-4139-AED7-4FB6502F622B}.Release|x64.Build.0 = Release|Any CPU
 | 
			
		||||
		{490CC8AF-C47C-4139-AED7-4FB6502F622B}.Release|x86.ActiveCfg = Release|Any CPU
 | 
			
		||||
		{490CC8AF-C47C-4139-AED7-4FB6502F622B}.Release|x86.Build.0 = Release|Any CPU
 | 
			
		||||
		{C32C7D4A-76D2-4A43-9A41-4B0440819954}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
 | 
			
		||||
		{C32C7D4A-76D2-4A43-9A41-4B0440819954}.Debug|Any CPU.Build.0 = Debug|Any CPU
 | 
			
		||||
		{C32C7D4A-76D2-4A43-9A41-4B0440819954}.Debug|x64.ActiveCfg = Debug|Any CPU
 | 
			
		||||
		{C32C7D4A-76D2-4A43-9A41-4B0440819954}.Debug|x64.Build.0 = Debug|Any CPU
 | 
			
		||||
		{C32C7D4A-76D2-4A43-9A41-4B0440819954}.Debug|x86.ActiveCfg = Debug|Any CPU
 | 
			
		||||
		{C32C7D4A-76D2-4A43-9A41-4B0440819954}.Debug|x86.Build.0 = Debug|Any CPU
 | 
			
		||||
		{C32C7D4A-76D2-4A43-9A41-4B0440819954}.Release|Any CPU.ActiveCfg = Release|Any CPU
 | 
			
		||||
		{C32C7D4A-76D2-4A43-9A41-4B0440819954}.Release|Any CPU.Build.0 = Release|Any CPU
 | 
			
		||||
		{C32C7D4A-76D2-4A43-9A41-4B0440819954}.Release|x64.ActiveCfg = Release|Any CPU
 | 
			
		||||
		{C32C7D4A-76D2-4A43-9A41-4B0440819954}.Release|x64.Build.0 = Release|Any CPU
 | 
			
		||||
		{C32C7D4A-76D2-4A43-9A41-4B0440819954}.Release|x86.ActiveCfg = Release|Any CPU
 | 
			
		||||
		{C32C7D4A-76D2-4A43-9A41-4B0440819954}.Release|x86.Build.0 = Release|Any CPU
 | 
			
		||||
	EndGlobalSection
 | 
			
		||||
	GlobalSection(SolutionProperties) = preSolution
 | 
			
		||||
		HideSolutionNode = FALSE
 | 
			
		||||
	EndGlobalSection
 | 
			
		||||
	GlobalSection(NestedProjects) = preSolution
 | 
			
		||||
		{C32C7D4A-76D2-4A43-9A41-4B0440819954} = {94C8A78D-AA15-47B2-A348-530CD86BFC1B}
 | 
			
		||||
	EndGlobalSection
 | 
			
		||||
	GlobalSection(ExtensibilityGlobals) = postSolution
 | 
			
		||||
		SolutionGuid = {089687FD-5D25-40AB-BA8A-A10D1E137F98}
 | 
			
		||||
	EndGlobalSection
 | 
			
		||||
 
 | 
			
		||||
@@ -41,7 +41,3 @@
 | 
			
		||||
	public static string FormatSqlite (this string that, params object[] args) => _sqliteAdo.Addslashes(that, args);
 | 
			
		||||
	static FreeSql.Sqlite.SqliteAdo _sqliteAdo = new FreeSql.Sqlite.SqliteAdo();
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
namespace System.Runtime.CompilerServices {
 | 
			
		||||
	public class ExtensionAttribute : Attribute { }
 | 
			
		||||
}
 | 
			
		||||
@@ -34,16 +34,20 @@ namespace FreeSql.Internal {
 | 
			
		||||
 | 
			
		||||
		ConcurrentDictionary<Type, TableAttribute> dicConfigEntity = new ConcurrentDictionary<Type, TableAttribute>();
 | 
			
		||||
		internal ICodeFirst ConfigEntity<T>(Action<TableFluent<T>> entity) {
 | 
			
		||||
			if (entity == null) return _orm.CodeFirst;
 | 
			
		||||
			var type = typeof(T);
 | 
			
		||||
			var table = dicConfigEntity.GetOrAdd(type, new TableAttribute());
 | 
			
		||||
			var fluent = new TableFluent<T>(table);
 | 
			
		||||
			entity?.Invoke(fluent);
 | 
			
		||||
			entity.Invoke(fluent);
 | 
			
		||||
			Utils.GetTableByEntity(type, this, true); //update cache
 | 
			
		||||
			return _orm.CodeFirst;
 | 
			
		||||
		}
 | 
			
		||||
		internal ICodeFirst ConfigEntity(Type type, Action<TableFluent> entity) {
 | 
			
		||||
			if (entity == null) return _orm.CodeFirst;
 | 
			
		||||
			var table = dicConfigEntity.GetOrAdd(type, new TableAttribute());
 | 
			
		||||
			var fluent = new TableFluent(type, table);
 | 
			
		||||
			entity?.Invoke(fluent);
 | 
			
		||||
			entity.Invoke(fluent);
 | 
			
		||||
			Utils.GetTableByEntity(type, this, true); //update cache
 | 
			
		||||
			return _orm.CodeFirst;
 | 
			
		||||
		}
 | 
			
		||||
		internal TableAttribute GetEntityTableAttribute(Type type) {
 | 
			
		||||
 
 | 
			
		||||
@@ -24,10 +24,10 @@ namespace FreeSql.Internal {
 | 
			
		||||
	class Utils {
 | 
			
		||||
 | 
			
		||||
		static ConcurrentDictionary<string, ConcurrentDictionary<Type, TableInfo>> _cacheGetTableByEntity = new ConcurrentDictionary<string, ConcurrentDictionary<Type, TableInfo>>();
 | 
			
		||||
		internal static TableInfo GetTableByEntity(Type entity, CommonUtils common) {
 | 
			
		||||
		internal static TableInfo GetTableByEntity(Type entity, CommonUtils common, bool isReCache = false) {
 | 
			
		||||
			if (entity.FullName.StartsWith("<>f__AnonymousType")) return null;
 | 
			
		||||
			var tbc = _cacheGetTableByEntity.GetOrAdd(common.DbName, k1 => new ConcurrentDictionary<Type, TableInfo>()); //区分数据库类型缓存
 | 
			
		||||
			if (tbc.TryGetValue(entity, out var trytb)) return trytb;
 | 
			
		||||
			if (isReCache == false && tbc.TryGetValue(entity, out var trytb)) return trytb;
 | 
			
		||||
			if (common.CodeFirst.GetDbInfo(entity) != null) return null;
 | 
			
		||||
 | 
			
		||||
			var tbattr = common.GetEntityTableAttribute(entity);
 | 
			
		||||
@@ -105,7 +105,7 @@ namespace FreeSql.Internal {
 | 
			
		||||
				foreach (var col in trytb.Primarys)
 | 
			
		||||
					col.Attribute.IsPrimary = true;
 | 
			
		||||
			}
 | 
			
		||||
			tbc.TryAdd(entity, trytb);
 | 
			
		||||
			tbc.AddOrUpdate(entity, trytb, (oldkey, oldval) => trytb);
 | 
			
		||||
 | 
			
		||||
			#region virtual 属性延时加载,动态产生新的重写类
 | 
			
		||||
			if (common.CodeFirst.IsLazyLoading && propsLazy.Any()) {
 | 
			
		||||
 
 | 
			
		||||
@@ -1,280 +1,280 @@
 | 
			
		||||
using FreeSql.DataAnnotations;
 | 
			
		||||
using FreeSql.Internal.Model;
 | 
			
		||||
using Newtonsoft.Json.Linq;
 | 
			
		||||
using Npgsql.LegacyPostgis;
 | 
			
		||||
using NpgsqlTypes;
 | 
			
		||||
using System;
 | 
			
		||||
using System.Collections;
 | 
			
		||||
using System.Collections.Concurrent;
 | 
			
		||||
using System.Collections.Generic;
 | 
			
		||||
using System.Diagnostics;
 | 
			
		||||
using System.Linq;
 | 
			
		||||
using System.Net;
 | 
			
		||||
using System.Net.NetworkInformation;
 | 
			
		||||
using System.Reflection;
 | 
			
		||||
using System.Text.RegularExpressions;
 | 
			
		||||
using System.Threading;
 | 
			
		||||
//using FreeSql.DataAnnotations;
 | 
			
		||||
//using FreeSql.Internal.Model;
 | 
			
		||||
//using Newtonsoft.Json.Linq;
 | 
			
		||||
//using Npgsql.LegacyPostgis;
 | 
			
		||||
//using NpgsqlTypes;
 | 
			
		||||
//using System;
 | 
			
		||||
//using System.Collections;
 | 
			
		||||
//using System.Collections.Concurrent;
 | 
			
		||||
//using System.Collections.Generic;
 | 
			
		||||
//using System.Diagnostics;
 | 
			
		||||
//using System.Linq;
 | 
			
		||||
//using System.Net;
 | 
			
		||||
//using System.Net.NetworkInformation;
 | 
			
		||||
//using System.Reflection;
 | 
			
		||||
//using System.Text.RegularExpressions;
 | 
			
		||||
//using System.Threading;
 | 
			
		||||
 | 
			
		||||
namespace FreeSql.Internal {
 | 
			
		||||
	class UtilsReflection {
 | 
			
		||||
//namespace FreeSql.Internal {
 | 
			
		||||
//	class UtilsReflection {
 | 
			
		||||
 | 
			
		||||
		static ConcurrentDictionary<string, TableInfo> _cacheGetTableByEntity = new ConcurrentDictionary<string, TableInfo>();
 | 
			
		||||
		internal static TableInfo GetTableByEntity(Type entity, CommonUtils common) {
 | 
			
		||||
			if (entity.FullName.StartsWith("<>f__AnonymousType")) return null;
 | 
			
		||||
			if (_cacheGetTableByEntity.TryGetValue($"{common.DbName}-{entity.FullName}", out var trytb)) return trytb; //区分数据库类型缓存
 | 
			
		||||
			if (common.CodeFirst.GetDbInfo(entity) != null) return null;
 | 
			
		||||
//		static ConcurrentDictionary<string, TableInfo> _cacheGetTableByEntity = new ConcurrentDictionary<string, TableInfo>();
 | 
			
		||||
//		internal static TableInfo GetTableByEntity(Type entity, CommonUtils common) {
 | 
			
		||||
//			if (entity.FullName.StartsWith("<>f__AnonymousType")) return null;
 | 
			
		||||
//			if (_cacheGetTableByEntity.TryGetValue($"{common.DbName}-{entity.FullName}", out var trytb)) return trytb; //区分数据库类型缓存
 | 
			
		||||
//			if (common.CodeFirst.GetDbInfo(entity) != null) return null;
 | 
			
		||||
 | 
			
		||||
			var tbattr = entity.GetCustomAttributes(typeof(TableAttribute), false).LastOrDefault() as TableAttribute;
 | 
			
		||||
			trytb = new TableInfo();
 | 
			
		||||
			trytb.Type = entity;
 | 
			
		||||
			trytb.Properties = entity.GetProperties().ToDictionary(a => a.Name, a => a, StringComparer.CurrentCultureIgnoreCase);
 | 
			
		||||
			trytb.CsName = entity.Name;
 | 
			
		||||
			trytb.DbName = (tbattr?.Name ?? entity.Name);
 | 
			
		||||
			trytb.DbOldName = tbattr?.OldName;
 | 
			
		||||
			if (common.CodeFirst.IsSyncStructureToLower) {
 | 
			
		||||
				trytb.DbName = trytb.DbName.ToLower();
 | 
			
		||||
				trytb.DbOldName = trytb.DbOldName?.ToLower();
 | 
			
		||||
			}
 | 
			
		||||
			trytb.SelectFilter = tbattr?.SelectFilter;
 | 
			
		||||
			foreach (var p in trytb.Properties.Values) {
 | 
			
		||||
				var tp = common.CodeFirst.GetDbInfo(p.PropertyType);
 | 
			
		||||
				//if (tp == null) continue;
 | 
			
		||||
				var colattr = p.GetCustomAttributes(typeof(ColumnAttribute), false).LastOrDefault() as ColumnAttribute;
 | 
			
		||||
				if (tp == null && colattr == null) continue;
 | 
			
		||||
				if (colattr == null)
 | 
			
		||||
					colattr = new ColumnAttribute {
 | 
			
		||||
						Name = p.Name,
 | 
			
		||||
						DbType = tp.Value.dbtypeFull,
 | 
			
		||||
						IsIdentity = false,
 | 
			
		||||
						IsNullable = tp.Value.isnullable ?? true,
 | 
			
		||||
						IsPrimary = false,
 | 
			
		||||
					};
 | 
			
		||||
				if (string.IsNullOrEmpty(colattr.DbType)) colattr.DbType = tp?.dbtypeFull ?? "varchar(255)";
 | 
			
		||||
				colattr.DbType = colattr.DbType.ToUpper();
 | 
			
		||||
//			var tbattr = entity.GetCustomAttributes(typeof(TableAttribute), false).LastOrDefault() as TableAttribute;
 | 
			
		||||
//			trytb = new TableInfo();
 | 
			
		||||
//			trytb.Type = entity;
 | 
			
		||||
//			trytb.Properties = entity.GetProperties().ToDictionary(a => a.Name, a => a, StringComparer.CurrentCultureIgnoreCase);
 | 
			
		||||
//			trytb.CsName = entity.Name;
 | 
			
		||||
//			trytb.DbName = (tbattr?.Name ?? entity.Name);
 | 
			
		||||
//			trytb.DbOldName = tbattr?.OldName;
 | 
			
		||||
//			if (common.CodeFirst.IsSyncStructureToLower) {
 | 
			
		||||
//				trytb.DbName = trytb.DbName.ToLower();
 | 
			
		||||
//				trytb.DbOldName = trytb.DbOldName?.ToLower();
 | 
			
		||||
//			}
 | 
			
		||||
//			trytb.SelectFilter = tbattr?.SelectFilter;
 | 
			
		||||
//			foreach (var p in trytb.Properties.Values) {
 | 
			
		||||
//				var tp = common.CodeFirst.GetDbInfo(p.PropertyType);
 | 
			
		||||
//				//if (tp == null) continue;
 | 
			
		||||
//				var colattr = p.GetCustomAttributes(typeof(ColumnAttribute), false).LastOrDefault() as ColumnAttribute;
 | 
			
		||||
//				if (tp == null && colattr == null) continue;
 | 
			
		||||
//				if (colattr == null)
 | 
			
		||||
//					colattr = new ColumnAttribute {
 | 
			
		||||
//						Name = p.Name,
 | 
			
		||||
//						DbType = tp.Value.dbtypeFull,
 | 
			
		||||
//						IsIdentity = false,
 | 
			
		||||
//						IsNullable = tp.Value.isnullable ?? true,
 | 
			
		||||
//						IsPrimary = false,
 | 
			
		||||
//					};
 | 
			
		||||
//				if (string.IsNullOrEmpty(colattr.DbType)) colattr.DbType = tp?.dbtypeFull ?? "varchar(255)";
 | 
			
		||||
//				colattr.DbType = colattr.DbType.ToUpper();
 | 
			
		||||
 | 
			
		||||
				if (tp != null && tp.Value.isnullable == null) colattr.IsNullable = tp.Value.dbtypeFull.Contains("NOT NULL") == false;
 | 
			
		||||
				if (colattr.DbType?.Contains("NOT NULL") == true) colattr.IsNullable = false;
 | 
			
		||||
				if (string.IsNullOrEmpty(colattr.Name)) colattr.Name = p.Name;
 | 
			
		||||
				if (common.CodeFirst.IsSyncStructureToLower) colattr.Name = colattr.Name.ToLower();
 | 
			
		||||
//				if (tp != null && tp.Value.isnullable == null) colattr.IsNullable = tp.Value.dbtypeFull.Contains("NOT NULL") == false;
 | 
			
		||||
//				if (colattr.DbType?.Contains("NOT NULL") == true) colattr.IsNullable = false;
 | 
			
		||||
//				if (string.IsNullOrEmpty(colattr.Name)) colattr.Name = p.Name;
 | 
			
		||||
//				if (common.CodeFirst.IsSyncStructureToLower) colattr.Name = colattr.Name.ToLower();
 | 
			
		||||
 | 
			
		||||
				if ((colattr.IsNullable != true || colattr.IsIdentity == true || colattr.IsPrimary == true) && colattr.DbType.Contains("NOT NULL") == false) {
 | 
			
		||||
					colattr.IsNullable = false;
 | 
			
		||||
					colattr.DbType += " NOT NULL";
 | 
			
		||||
				}
 | 
			
		||||
				if (colattr.IsNullable == true && colattr.DbType.Contains("NOT NULL")) colattr.DbType = colattr.DbType.Replace("NOT NULL", "");
 | 
			
		||||
				colattr.DbType = Regex.Replace(colattr.DbType, @"\([^\)]+\)", m => {
 | 
			
		||||
					var tmpLt = Regex.Replace(m.Groups[0].Value, @"\s", "");
 | 
			
		||||
					if (tmpLt.Contains("CHAR")) tmpLt = tmpLt.Replace("CHAR", " CHAR");
 | 
			
		||||
					if (tmpLt.Contains("BYTE")) tmpLt = tmpLt.Replace("BYTE", " BYTE");
 | 
			
		||||
					return tmpLt;
 | 
			
		||||
				});
 | 
			
		||||
				colattr.DbDefautValue = trytb.Properties[p.Name].GetValue(Activator.CreateInstance(trytb.Type));
 | 
			
		||||
				if (colattr.DbDefautValue == null) colattr.DbDefautValue = tp?.defaultValue;
 | 
			
		||||
				if (colattr.IsNullable == false && colattr.DbDefautValue == null)
 | 
			
		||||
					colattr.DbDefautValue = Activator.CreateInstance(p.PropertyType.IsNullableType() ? p.PropertyType.GenericTypeArguments.FirstOrDefault() : p.PropertyType);
 | 
			
		||||
//				if ((colattr.IsNullable != true || colattr.IsIdentity == true || colattr.IsPrimary == true) && colattr.DbType.Contains("NOT NULL") == false) {
 | 
			
		||||
//					colattr.IsNullable = false;
 | 
			
		||||
//					colattr.DbType += " NOT NULL";
 | 
			
		||||
//				}
 | 
			
		||||
//				if (colattr.IsNullable == true && colattr.DbType.Contains("NOT NULL")) colattr.DbType = colattr.DbType.Replace("NOT NULL", "");
 | 
			
		||||
//				colattr.DbType = Regex.Replace(colattr.DbType, @"\([^\)]+\)", m => {
 | 
			
		||||
//					var tmpLt = Regex.Replace(m.Groups[0].Value, @"\s", "");
 | 
			
		||||
//					if (tmpLt.Contains("CHAR")) tmpLt = tmpLt.Replace("CHAR", " CHAR");
 | 
			
		||||
//					if (tmpLt.Contains("BYTE")) tmpLt = tmpLt.Replace("BYTE", " BYTE");
 | 
			
		||||
//					return tmpLt;
 | 
			
		||||
//				});
 | 
			
		||||
//				colattr.DbDefautValue = trytb.Properties[p.Name].GetValue(Activator.CreateInstance(trytb.Type));
 | 
			
		||||
//				if (colattr.DbDefautValue == null) colattr.DbDefautValue = tp?.defaultValue;
 | 
			
		||||
//				if (colattr.IsNullable == false && colattr.DbDefautValue == null)
 | 
			
		||||
//					colattr.DbDefautValue = Activator.CreateInstance(p.PropertyType.IsNullableType() ? p.PropertyType.GenericTypeArguments.FirstOrDefault() : p.PropertyType);
 | 
			
		||||
 | 
			
		||||
				var col = new ColumnInfo {
 | 
			
		||||
					Table = trytb,
 | 
			
		||||
					CsName = p.Name,
 | 
			
		||||
					CsType = p.PropertyType,
 | 
			
		||||
					Attribute = colattr
 | 
			
		||||
				};
 | 
			
		||||
				trytb.Columns.Add(colattr.Name, col);
 | 
			
		||||
				trytb.ColumnsByCs.Add(p.Name, col);
 | 
			
		||||
			}
 | 
			
		||||
			trytb.Primarys = trytb.Columns.Values.Where(a => a.Attribute.IsPrimary == true).ToArray();
 | 
			
		||||
			if (trytb.Primarys.Any() == false) {
 | 
			
		||||
				trytb.Primarys = trytb.Columns.Values.Where(a => a.Attribute.IsIdentity == true).ToArray();
 | 
			
		||||
				foreach(var col in trytb.Primarys)
 | 
			
		||||
					col.Attribute.IsPrimary = true;
 | 
			
		||||
			}
 | 
			
		||||
			_cacheGetTableByEntity.TryAdd(entity.FullName, trytb);
 | 
			
		||||
			return trytb;
 | 
			
		||||
		}
 | 
			
		||||
//				var col = new ColumnInfo {
 | 
			
		||||
//					Table = trytb,
 | 
			
		||||
//					CsName = p.Name,
 | 
			
		||||
//					CsType = p.PropertyType,
 | 
			
		||||
//					Attribute = colattr
 | 
			
		||||
//				};
 | 
			
		||||
//				trytb.Columns.Add(colattr.Name, col);
 | 
			
		||||
//				trytb.ColumnsByCs.Add(p.Name, col);
 | 
			
		||||
//			}
 | 
			
		||||
//			trytb.Primarys = trytb.Columns.Values.Where(a => a.Attribute.IsPrimary == true).ToArray();
 | 
			
		||||
//			if (trytb.Primarys.Any() == false) {
 | 
			
		||||
//				trytb.Primarys = trytb.Columns.Values.Where(a => a.Attribute.IsIdentity == true).ToArray();
 | 
			
		||||
//				foreach(var col in trytb.Primarys)
 | 
			
		||||
//					col.Attribute.IsPrimary = true;
 | 
			
		||||
//			}
 | 
			
		||||
//			_cacheGetTableByEntity.TryAdd(entity.FullName, trytb);
 | 
			
		||||
//			return trytb;
 | 
			
		||||
//		}
 | 
			
		||||
 | 
			
		||||
		internal static T[] GetDbParamtersByObject<T>(string sql, object obj, string paramPrefix, Func<string, Type, object, T> constructorParamter) {
 | 
			
		||||
			if (string.IsNullOrEmpty(sql) || obj == null) return new T[0];
 | 
			
		||||
			var ttype = typeof(T);
 | 
			
		||||
			var type = obj.GetType();
 | 
			
		||||
			if (type == ttype) return new[] { (T)Convert.ChangeType(obj, type) };
 | 
			
		||||
			var ret = new List<T>();
 | 
			
		||||
			var ps = type.GetProperties();
 | 
			
		||||
			foreach (var p in ps) {
 | 
			
		||||
				if (sql.IndexOf($"{paramPrefix}{p.Name}", StringComparison.CurrentCultureIgnoreCase) == -1) continue;
 | 
			
		||||
				var pvalue = p.GetValue(obj);
 | 
			
		||||
				if (p.PropertyType == ttype) ret.Add((T)Convert.ChangeType(pvalue, ttype));
 | 
			
		||||
				else ret.Add(constructorParamter(p.Name, p.PropertyType, pvalue));
 | 
			
		||||
			}
 | 
			
		||||
			return ret.ToArray();
 | 
			
		||||
		}
 | 
			
		||||
//		internal static T[] GetDbParamtersByObject<T>(string sql, object obj, string paramPrefix, Func<string, Type, object, T> constructorParamter) {
 | 
			
		||||
//			if (string.IsNullOrEmpty(sql) || obj == null) return new T[0];
 | 
			
		||||
//			var ttype = typeof(T);
 | 
			
		||||
//			var type = obj.GetType();
 | 
			
		||||
//			if (type == ttype) return new[] { (T)Convert.ChangeType(obj, type) };
 | 
			
		||||
//			var ret = new List<T>();
 | 
			
		||||
//			var ps = type.GetProperties();
 | 
			
		||||
//			foreach (var p in ps) {
 | 
			
		||||
//				if (sql.IndexOf($"{paramPrefix}{p.Name}", StringComparison.CurrentCultureIgnoreCase) == -1) continue;
 | 
			
		||||
//				var pvalue = p.GetValue(obj);
 | 
			
		||||
//				if (p.PropertyType == ttype) ret.Add((T)Convert.ChangeType(pvalue, ttype));
 | 
			
		||||
//				else ret.Add(constructorParamter(p.Name, p.PropertyType, pvalue));
 | 
			
		||||
//			}
 | 
			
		||||
//			return ret.ToArray();
 | 
			
		||||
//		}
 | 
			
		||||
 | 
			
		||||
		static Dictionary<Type, bool> dicExecuteArrayRowReadClassOrTuple = new Dictionary<Type, bool> {
 | 
			
		||||
			[typeof(bool)] = true,
 | 
			
		||||
			[typeof(sbyte)] = true,
 | 
			
		||||
			[typeof(short)] = true,
 | 
			
		||||
			[typeof(int)] = true,
 | 
			
		||||
			[typeof(long)] = true,
 | 
			
		||||
			[typeof(byte)] = true,
 | 
			
		||||
			[typeof(ushort)] = true,
 | 
			
		||||
			[typeof(uint)] = true,
 | 
			
		||||
			[typeof(ulong)] = true,
 | 
			
		||||
			[typeof(double)] = true,
 | 
			
		||||
			[typeof(float)] = true,
 | 
			
		||||
			[typeof(decimal)] = true,
 | 
			
		||||
			[typeof(TimeSpan)] = true,
 | 
			
		||||
			[typeof(DateTime)] = true,
 | 
			
		||||
			[typeof(DateTimeOffset)] = true,
 | 
			
		||||
			[typeof(byte[])] = true,
 | 
			
		||||
			[typeof(string)] = true,
 | 
			
		||||
			[typeof(Guid)] = true,
 | 
			
		||||
			[typeof(MygisPoint)] = true,
 | 
			
		||||
			[typeof(MygisLineString)] = true,
 | 
			
		||||
			[typeof(MygisPolygon)] = true,
 | 
			
		||||
			[typeof(MygisMultiPoint)] = true,
 | 
			
		||||
			[typeof(MygisMultiLineString)] = true,
 | 
			
		||||
			[typeof(MygisMultiPolygon)] = true,
 | 
			
		||||
			[typeof(BitArray)] = true,
 | 
			
		||||
			[typeof(NpgsqlPoint)] = true,
 | 
			
		||||
			[typeof(NpgsqlLine)] = true,
 | 
			
		||||
			[typeof(NpgsqlLSeg)] = true,
 | 
			
		||||
			[typeof(NpgsqlBox)] = true,
 | 
			
		||||
			[typeof(NpgsqlPath)] = true,
 | 
			
		||||
			[typeof(NpgsqlPolygon)] = true,
 | 
			
		||||
			[typeof(NpgsqlCircle)] = true,
 | 
			
		||||
			[typeof((IPAddress Address, int Subnet))] = true,
 | 
			
		||||
			[typeof(IPAddress)] = true,
 | 
			
		||||
			[typeof(PhysicalAddress)] = true,
 | 
			
		||||
			[typeof(NpgsqlRange<int>)] = true,
 | 
			
		||||
			[typeof(NpgsqlRange<long>)] = true,
 | 
			
		||||
			[typeof(NpgsqlRange<decimal>)] = true,
 | 
			
		||||
			[typeof(NpgsqlRange<DateTime>)] = true,
 | 
			
		||||
			[typeof(PostgisPoint)] = true,
 | 
			
		||||
			[typeof(PostgisLineString)] = true,
 | 
			
		||||
			[typeof(PostgisPolygon)] = true,
 | 
			
		||||
			[typeof(PostgisMultiPoint)] = true,
 | 
			
		||||
			[typeof(PostgisMultiLineString)] = true,
 | 
			
		||||
			[typeof(PostgisMultiPolygon)] = true,
 | 
			
		||||
			[typeof(PostgisGeometry)] = true,
 | 
			
		||||
			[typeof(PostgisGeometryCollection)] = true,
 | 
			
		||||
			[typeof(Dictionary<string, string>)] = true,
 | 
			
		||||
			[typeof(JToken)] = true,
 | 
			
		||||
			[typeof(JObject)] = true,
 | 
			
		||||
			[typeof(JArray)] = true,
 | 
			
		||||
		};
 | 
			
		||||
//		static Dictionary<Type, bool> dicExecuteArrayRowReadClassOrTuple = new Dictionary<Type, bool> {
 | 
			
		||||
//			[typeof(bool)] = true,
 | 
			
		||||
//			[typeof(sbyte)] = true,
 | 
			
		||||
//			[typeof(short)] = true,
 | 
			
		||||
//			[typeof(int)] = true,
 | 
			
		||||
//			[typeof(long)] = true,
 | 
			
		||||
//			[typeof(byte)] = true,
 | 
			
		||||
//			[typeof(ushort)] = true,
 | 
			
		||||
//			[typeof(uint)] = true,
 | 
			
		||||
//			[typeof(ulong)] = true,
 | 
			
		||||
//			[typeof(double)] = true,
 | 
			
		||||
//			[typeof(float)] = true,
 | 
			
		||||
//			[typeof(decimal)] = true,
 | 
			
		||||
//			[typeof(TimeSpan)] = true,
 | 
			
		||||
//			[typeof(DateTime)] = true,
 | 
			
		||||
//			[typeof(DateTimeOffset)] = true,
 | 
			
		||||
//			[typeof(byte[])] = true,
 | 
			
		||||
//			[typeof(string)] = true,
 | 
			
		||||
//			[typeof(Guid)] = true,
 | 
			
		||||
//			[typeof(MygisPoint)] = true,
 | 
			
		||||
//			[typeof(MygisLineString)] = true,
 | 
			
		||||
//			[typeof(MygisPolygon)] = true,
 | 
			
		||||
//			[typeof(MygisMultiPoint)] = true,
 | 
			
		||||
//			[typeof(MygisMultiLineString)] = true,
 | 
			
		||||
//			[typeof(MygisMultiPolygon)] = true,
 | 
			
		||||
//			[typeof(BitArray)] = true,
 | 
			
		||||
//			[typeof(NpgsqlPoint)] = true,
 | 
			
		||||
//			[typeof(NpgsqlLine)] = true,
 | 
			
		||||
//			[typeof(NpgsqlLSeg)] = true,
 | 
			
		||||
//			[typeof(NpgsqlBox)] = true,
 | 
			
		||||
//			[typeof(NpgsqlPath)] = true,
 | 
			
		||||
//			[typeof(NpgsqlPolygon)] = true,
 | 
			
		||||
//			[typeof(NpgsqlCircle)] = true,
 | 
			
		||||
//			[typeof((IPAddress Address, int Subnet))] = true,
 | 
			
		||||
//			[typeof(IPAddress)] = true,
 | 
			
		||||
//			[typeof(PhysicalAddress)] = true,
 | 
			
		||||
//			[typeof(NpgsqlRange<int>)] = true,
 | 
			
		||||
//			[typeof(NpgsqlRange<long>)] = true,
 | 
			
		||||
//			[typeof(NpgsqlRange<decimal>)] = true,
 | 
			
		||||
//			[typeof(NpgsqlRange<DateTime>)] = true,
 | 
			
		||||
//			[typeof(PostgisPoint)] = true,
 | 
			
		||||
//			[typeof(PostgisLineString)] = true,
 | 
			
		||||
//			[typeof(PostgisPolygon)] = true,
 | 
			
		||||
//			[typeof(PostgisMultiPoint)] = true,
 | 
			
		||||
//			[typeof(PostgisMultiLineString)] = true,
 | 
			
		||||
//			[typeof(PostgisMultiPolygon)] = true,
 | 
			
		||||
//			[typeof(PostgisGeometry)] = true,
 | 
			
		||||
//			[typeof(PostgisGeometryCollection)] = true,
 | 
			
		||||
//			[typeof(Dictionary<string, string>)] = true,
 | 
			
		||||
//			[typeof(JToken)] = true,
 | 
			
		||||
//			[typeof(JObject)] = true,
 | 
			
		||||
//			[typeof(JArray)] = true,
 | 
			
		||||
//		};
 | 
			
		||||
 | 
			
		||||
		internal static ConcurrentDictionary<Type, _dicClassConstructorInfo> _dicClassConstructor = new ConcurrentDictionary<Type, _dicClassConstructorInfo>();
 | 
			
		||||
		internal static ConcurrentDictionary<Type, _dicTupleConstructorInfo> _dicTupleConstructor = new ConcurrentDictionary<Type, _dicTupleConstructorInfo>();
 | 
			
		||||
		internal class _dicClassConstructorInfo {
 | 
			
		||||
			public ConstructorInfo Constructor { get; set; }
 | 
			
		||||
			public PropertyInfo[] Properties { get; set; }
 | 
			
		||||
		}
 | 
			
		||||
		internal class _dicTupleConstructorInfo {
 | 
			
		||||
			public ConstructorInfo Constructor { get; set; }
 | 
			
		||||
			public Type[] Types { get; set; }
 | 
			
		||||
		}
 | 
			
		||||
		internal static (object value, int dataIndex) ExecuteArrayRowReadClassOrTuple(Type type, Dictionary<string, int> names, object[] row, int dataIndex = 0) {
 | 
			
		||||
			if (type.IsArray) return (GetDataReaderValue(type, row[dataIndex]), dataIndex + 1);
 | 
			
		||||
			var typeGeneric = type;
 | 
			
		||||
			if (typeGeneric.IsNullableType()) typeGeneric = type.GenericTypeArguments.First();
 | 
			
		||||
			if (typeGeneric.IsEnum ||
 | 
			
		||||
				dicExecuteArrayRowReadClassOrTuple.ContainsKey(typeGeneric))
 | 
			
		||||
				return (GetDataReaderValue(type, row[dataIndex]), dataIndex + 1);
 | 
			
		||||
			if (type.Namespace == "System" && (type.FullName == "System.String" || type.IsValueType)) { //值类型,或者元组
 | 
			
		||||
				bool isTuple = type.Name.StartsWith("ValueTuple`");
 | 
			
		||||
				if (isTuple) {
 | 
			
		||||
					if (_dicTupleConstructor.TryGetValue(type, out var tupleInfo) == false) {
 | 
			
		||||
						var types = type.GetFields().Select(a => a.FieldType).ToArray();
 | 
			
		||||
						tupleInfo = new _dicTupleConstructorInfo { Constructor = type.GetConstructor(types), Types = types };
 | 
			
		||||
						_dicTupleConstructor.AddOrUpdate(type, tupleInfo, (t2, c2) => tupleInfo);
 | 
			
		||||
					}
 | 
			
		||||
					var parms = new object[tupleInfo.Types.Length];
 | 
			
		||||
					for (int a = 0; a < parms.Length; a++) {
 | 
			
		||||
						var read = ExecuteArrayRowReadClassOrTuple(tupleInfo.Types[a], names, row, dataIndex);
 | 
			
		||||
						if (read.dataIndex > dataIndex) dataIndex = read.dataIndex;
 | 
			
		||||
						parms[a] = read.value;
 | 
			
		||||
					}
 | 
			
		||||
					return (tupleInfo.Constructor?.Invoke(parms), dataIndex);
 | 
			
		||||
				}
 | 
			
		||||
				return (dataIndex >= row.Length || (row[dataIndex] ?? DBNull.Value) == DBNull.Value ? null : GetDataReaderValue(type, row[dataIndex]), dataIndex + 1);
 | 
			
		||||
			}
 | 
			
		||||
			if (type == typeof(object) && names != null) {
 | 
			
		||||
				dynamic expando = new System.Dynamic.ExpandoObject(); //动态类型字段 可读可写
 | 
			
		||||
				var expandodic = (IDictionary<string, object>)expando;
 | 
			
		||||
				foreach (var name in names)
 | 
			
		||||
					expandodic.Add(name.Key, row[name.Value]);
 | 
			
		||||
				return (expando, names.Count);
 | 
			
		||||
			}
 | 
			
		||||
			//类注入属性
 | 
			
		||||
			if (_dicClassConstructor.TryGetValue(type, out var classInfo)== false) {
 | 
			
		||||
				classInfo = new _dicClassConstructorInfo { Constructor = type.GetConstructor(new Type[0]), Properties = type.GetProperties() };
 | 
			
		||||
				_dicClassConstructor.TryAdd(type, classInfo);
 | 
			
		||||
			}
 | 
			
		||||
			var value = classInfo.Constructor.Invoke(new object[0]);
 | 
			
		||||
			foreach(var prop in classInfo.Properties) {
 | 
			
		||||
				var tryidx = dataIndex;
 | 
			
		||||
				if (names != null && names.TryGetValue(prop.Name, out tryidx) == false) continue;
 | 
			
		||||
				var read = ExecuteArrayRowReadClassOrTuple(prop.PropertyType, names, row, tryidx);
 | 
			
		||||
				if (read.dataIndex > dataIndex) dataIndex = read.dataIndex;
 | 
			
		||||
				prop.SetValue(value, read.value, null);
 | 
			
		||||
				//FillPropertyValue(value, p.Name, read.value);
 | 
			
		||||
				//p.SetValue(value, read.value);
 | 
			
		||||
			}
 | 
			
		||||
			return (value, dataIndex);
 | 
			
		||||
		}
 | 
			
		||||
//		internal static ConcurrentDictionary<Type, _dicClassConstructorInfo> _dicClassConstructor = new ConcurrentDictionary<Type, _dicClassConstructorInfo>();
 | 
			
		||||
//		internal static ConcurrentDictionary<Type, _dicTupleConstructorInfo> _dicTupleConstructor = new ConcurrentDictionary<Type, _dicTupleConstructorInfo>();
 | 
			
		||||
//		internal class _dicClassConstructorInfo {
 | 
			
		||||
//			public ConstructorInfo Constructor { get; set; }
 | 
			
		||||
//			public PropertyInfo[] Properties { get; set; }
 | 
			
		||||
//		}
 | 
			
		||||
//		internal class _dicTupleConstructorInfo {
 | 
			
		||||
//			public ConstructorInfo Constructor { get; set; }
 | 
			
		||||
//			public Type[] Types { get; set; }
 | 
			
		||||
//		}
 | 
			
		||||
//		internal static (object value, int dataIndex) ExecuteArrayRowReadClassOrTuple(Type type, Dictionary<string, int> names, object[] row, int dataIndex = 0) {
 | 
			
		||||
//			if (type.IsArray) return (GetDataReaderValue(type, row[dataIndex]), dataIndex + 1);
 | 
			
		||||
//			var typeGeneric = type;
 | 
			
		||||
//			if (typeGeneric.IsNullableType()) typeGeneric = type.GenericTypeArguments.First();
 | 
			
		||||
//			if (typeGeneric.IsEnum ||
 | 
			
		||||
//				dicExecuteArrayRowReadClassOrTuple.ContainsKey(typeGeneric))
 | 
			
		||||
//				return (GetDataReaderValue(type, row[dataIndex]), dataIndex + 1);
 | 
			
		||||
//			if (type.Namespace == "System" && (type.FullName == "System.String" || type.IsValueType)) { //值类型,或者元组
 | 
			
		||||
//				bool isTuple = type.Name.StartsWith("ValueTuple`");
 | 
			
		||||
//				if (isTuple) {
 | 
			
		||||
//					if (_dicTupleConstructor.TryGetValue(type, out var tupleInfo) == false) {
 | 
			
		||||
//						var types = type.GetFields().Select(a => a.FieldType).ToArray();
 | 
			
		||||
//						tupleInfo = new _dicTupleConstructorInfo { Constructor = type.GetConstructor(types), Types = types };
 | 
			
		||||
//						_dicTupleConstructor.AddOrUpdate(type, tupleInfo, (t2, c2) => tupleInfo);
 | 
			
		||||
//					}
 | 
			
		||||
//					var parms = new object[tupleInfo.Types.Length];
 | 
			
		||||
//					for (int a = 0; a < parms.Length; a++) {
 | 
			
		||||
//						var read = ExecuteArrayRowReadClassOrTuple(tupleInfo.Types[a], names, row, dataIndex);
 | 
			
		||||
//						if (read.dataIndex > dataIndex) dataIndex = read.dataIndex;
 | 
			
		||||
//						parms[a] = read.value;
 | 
			
		||||
//					}
 | 
			
		||||
//					return (tupleInfo.Constructor?.Invoke(parms), dataIndex);
 | 
			
		||||
//				}
 | 
			
		||||
//				return (dataIndex >= row.Length || (row[dataIndex] ?? DBNull.Value) == DBNull.Value ? null : GetDataReaderValue(type, row[dataIndex]), dataIndex + 1);
 | 
			
		||||
//			}
 | 
			
		||||
//			if (type == typeof(object) && names != null) {
 | 
			
		||||
//				dynamic expando = new System.Dynamic.ExpandoObject(); //动态类型字段 可读可写
 | 
			
		||||
//				var expandodic = (IDictionary<string, object>)expando;
 | 
			
		||||
//				foreach (var name in names)
 | 
			
		||||
//					expandodic.Add(name.Key, row[name.Value]);
 | 
			
		||||
//				return (expando, names.Count);
 | 
			
		||||
//			}
 | 
			
		||||
//			//类注入属性
 | 
			
		||||
//			if (_dicClassConstructor.TryGetValue(type, out var classInfo)== false) {
 | 
			
		||||
//				classInfo = new _dicClassConstructorInfo { Constructor = type.GetConstructor(new Type[0]), Properties = type.GetProperties() };
 | 
			
		||||
//				_dicClassConstructor.TryAdd(type, classInfo);
 | 
			
		||||
//			}
 | 
			
		||||
//			var value = classInfo.Constructor.Invoke(new object[0]);
 | 
			
		||||
//			foreach(var prop in classInfo.Properties) {
 | 
			
		||||
//				var tryidx = dataIndex;
 | 
			
		||||
//				if (names != null && names.TryGetValue(prop.Name, out tryidx) == false) continue;
 | 
			
		||||
//				var read = ExecuteArrayRowReadClassOrTuple(prop.PropertyType, names, row, tryidx);
 | 
			
		||||
//				if (read.dataIndex > dataIndex) dataIndex = read.dataIndex;
 | 
			
		||||
//				prop.SetValue(value, read.value, null);
 | 
			
		||||
//				//FillPropertyValue(value, p.Name, read.value);
 | 
			
		||||
//				//p.SetValue(value, read.value);
 | 
			
		||||
//			}
 | 
			
		||||
//			return (value, dataIndex);
 | 
			
		||||
//		}
 | 
			
		||||
 | 
			
		||||
		internal static void FillPropertyValue(object info, string memberAccessPath, object value) {
 | 
			
		||||
			var current = info;
 | 
			
		||||
			PropertyInfo prop = null;
 | 
			
		||||
			var members = memberAccessPath.Split('.');
 | 
			
		||||
			for (var a = 0; a < members.Length; a++) {
 | 
			
		||||
				var type = current.GetType();
 | 
			
		||||
				prop = type.GetProperty(members[a], BindingFlags.Public | BindingFlags.IgnoreCase | BindingFlags.Instance);
 | 
			
		||||
				if (prop == null) throw new Exception(string.Concat(type.FullName, " 没有定义属性 ", members[a]));
 | 
			
		||||
				if (a < members.Length - 1) current = prop.GetValue(current);
 | 
			
		||||
			}
 | 
			
		||||
			prop.SetValue(current, GetDataReaderValue(prop.PropertyType, value), null);
 | 
			
		||||
		}
 | 
			
		||||
		internal static object GetDataReaderValue(Type type, object value) {
 | 
			
		||||
			if (value == null || value == DBNull.Value) return null;
 | 
			
		||||
			if (type.FullName == "System.Byte[]") return value;
 | 
			
		||||
			if (type.IsArray) {
 | 
			
		||||
				var elementType = type.GetElementType();
 | 
			
		||||
				var valueArr = value as Array;
 | 
			
		||||
				if (elementType == valueArr.GetType().GetElementType()) return value;
 | 
			
		||||
				var len = valueArr.GetLength(0);
 | 
			
		||||
				var ret = Array.CreateInstance(elementType, len);
 | 
			
		||||
				for (var a = 0; a < len; a++) {
 | 
			
		||||
					var item = valueArr.GetValue(a);
 | 
			
		||||
					ret.SetValue(GetDataReaderValue(elementType, item), a);
 | 
			
		||||
				}
 | 
			
		||||
				return ret;
 | 
			
		||||
			}
 | 
			
		||||
			if (type.IsNullableType()) type = type.GenericTypeArguments.First();
 | 
			
		||||
			if (type.IsEnum) return Enum.Parse(type, string.Concat(value), true);
 | 
			
		||||
			switch(type.FullName) {
 | 
			
		||||
				case "System.Guid":
 | 
			
		||||
					if (value.GetType() != type) return Guid.TryParse(string.Concat(value), out var tryguid) ? tryguid : Guid.Empty;
 | 
			
		||||
					return value;
 | 
			
		||||
				case "MygisPoint": return MygisPoint.Parse(string.Concat(value)) as MygisPoint;
 | 
			
		||||
				case "MygisLineString": return MygisLineString.Parse(string.Concat(value)) as MygisLineString;
 | 
			
		||||
				case "MygisPolygon": return MygisPolygon.Parse(string.Concat(value)) as MygisPolygon;
 | 
			
		||||
				case "MygisMultiPoint": return MygisMultiPoint.Parse(string.Concat(value)) as MygisMultiPoint;
 | 
			
		||||
				case "MygisMultiLineString": return MygisMultiLineString.Parse(string.Concat(value)) as MygisMultiLineString;
 | 
			
		||||
				case "MygisMultiPolygon": return MygisMultiPolygon.Parse(string.Concat(value)) as MygisMultiPolygon;
 | 
			
		||||
				case "Newtonsoft.Json.Linq.JToken": return JToken.Parse(string.Concat(value));
 | 
			
		||||
				case "Newtonsoft.Json.Linq.JObject": return JObject.Parse(string.Concat(value));
 | 
			
		||||
				case "Newtonsoft.Json.Linq.JArray": return JArray.Parse(string.Concat(value));
 | 
			
		||||
				case "Npgsql.LegacyPostgis.PostgisGeometry": return value;
 | 
			
		||||
			}
 | 
			
		||||
			if (type != value.GetType()) {
 | 
			
		||||
				if (type.FullName == "System.TimeSpan") return TimeSpan.FromSeconds(double.Parse(value.ToString()));
 | 
			
		||||
				return Convert.ChangeType(value, type);
 | 
			
		||||
			}
 | 
			
		||||
			return value;
 | 
			
		||||
		}
 | 
			
		||||
		internal static string GetCsName(string name) {
 | 
			
		||||
			name = Regex.Replace(name.TrimStart('@'), @"[^\w]", "_");
 | 
			
		||||
			return char.IsLetter(name, 0) ? name : string.Concat("_", name);
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
}
 | 
			
		||||
//		internal static void FillPropertyValue(object info, string memberAccessPath, object value) {
 | 
			
		||||
//			var current = info;
 | 
			
		||||
//			PropertyInfo prop = null;
 | 
			
		||||
//			var members = memberAccessPath.Split('.');
 | 
			
		||||
//			for (var a = 0; a < members.Length; a++) {
 | 
			
		||||
//				var type = current.GetType();
 | 
			
		||||
//				prop = type.GetProperty(members[a], BindingFlags.Public | BindingFlags.IgnoreCase | BindingFlags.Instance);
 | 
			
		||||
//				if (prop == null) throw new Exception(string.Concat(type.FullName, " 没有定义属性 ", members[a]));
 | 
			
		||||
//				if (a < members.Length - 1) current = prop.GetValue(current);
 | 
			
		||||
//			}
 | 
			
		||||
//			prop.SetValue(current, GetDataReaderValue(prop.PropertyType, value), null);
 | 
			
		||||
//		}
 | 
			
		||||
//		internal static object GetDataReaderValue(Type type, object value) {
 | 
			
		||||
//			if (value == null || value == DBNull.Value) return null;
 | 
			
		||||
//			if (type.FullName == "System.Byte[]") return value;
 | 
			
		||||
//			if (type.IsArray) {
 | 
			
		||||
//				var elementType = type.GetElementType();
 | 
			
		||||
//				var valueArr = value as Array;
 | 
			
		||||
//				if (elementType == valueArr.GetType().GetElementType()) return value;
 | 
			
		||||
//				var len = valueArr.GetLength(0);
 | 
			
		||||
//				var ret = Array.CreateInstance(elementType, len);
 | 
			
		||||
//				for (var a = 0; a < len; a++) {
 | 
			
		||||
//					var item = valueArr.GetValue(a);
 | 
			
		||||
//					ret.SetValue(GetDataReaderValue(elementType, item), a);
 | 
			
		||||
//				}
 | 
			
		||||
//				return ret;
 | 
			
		||||
//			}
 | 
			
		||||
//			if (type.IsNullableType()) type = type.GenericTypeArguments.First();
 | 
			
		||||
//			if (type.IsEnum) return Enum.Parse(type, string.Concat(value), true);
 | 
			
		||||
//			switch(type.FullName) {
 | 
			
		||||
//				case "System.Guid":
 | 
			
		||||
//					if (value.GetType() != type) return Guid.TryParse(string.Concat(value), out var tryguid) ? tryguid : Guid.Empty;
 | 
			
		||||
//					return value;
 | 
			
		||||
//				case "MygisPoint": return MygisPoint.Parse(string.Concat(value)) as MygisPoint;
 | 
			
		||||
//				case "MygisLineString": return MygisLineString.Parse(string.Concat(value)) as MygisLineString;
 | 
			
		||||
//				case "MygisPolygon": return MygisPolygon.Parse(string.Concat(value)) as MygisPolygon;
 | 
			
		||||
//				case "MygisMultiPoint": return MygisMultiPoint.Parse(string.Concat(value)) as MygisMultiPoint;
 | 
			
		||||
//				case "MygisMultiLineString": return MygisMultiLineString.Parse(string.Concat(value)) as MygisMultiLineString;
 | 
			
		||||
//				case "MygisMultiPolygon": return MygisMultiPolygon.Parse(string.Concat(value)) as MygisMultiPolygon;
 | 
			
		||||
//				case "Newtonsoft.Json.Linq.JToken": return JToken.Parse(string.Concat(value));
 | 
			
		||||
//				case "Newtonsoft.Json.Linq.JObject": return JObject.Parse(string.Concat(value));
 | 
			
		||||
//				case "Newtonsoft.Json.Linq.JArray": return JArray.Parse(string.Concat(value));
 | 
			
		||||
//				case "Npgsql.LegacyPostgis.PostgisGeometry": return value;
 | 
			
		||||
//			}
 | 
			
		||||
//			if (type != value.GetType()) {
 | 
			
		||||
//				if (type.FullName == "System.TimeSpan") return TimeSpan.FromSeconds(double.Parse(value.ToString()));
 | 
			
		||||
//				return Convert.ChangeType(value, type);
 | 
			
		||||
//			}
 | 
			
		||||
//			return value;
 | 
			
		||||
//		}
 | 
			
		||||
//		internal static string GetCsName(string name) {
 | 
			
		||||
//			name = Regex.Replace(name.TrimStart('@'), @"[^\w]", "_");
 | 
			
		||||
//			return char.IsLetter(name, 0) ? name : string.Concat("_", name);
 | 
			
		||||
//		}
 | 
			
		||||
//	}
 | 
			
		||||
//}
 | 
			
		||||
@@ -11,7 +11,7 @@ using System.Threading.Tasks;
 | 
			
		||||
 | 
			
		||||
namespace FreeSql.Oracle {
 | 
			
		||||
 | 
			
		||||
	public class OracleConnectionPool : ObjectPool<DbConnection> {
 | 
			
		||||
	class OracleConnectionPool : ObjectPool<DbConnection> {
 | 
			
		||||
 | 
			
		||||
		internal Action availableHandler;
 | 
			
		||||
		internal Action unavailableHandler;
 | 
			
		||||
@@ -49,7 +49,7 @@ namespace FreeSql.Oracle {
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	public class OracleConnectionPoolPolicy : IPolicy<DbConnection> {
 | 
			
		||||
	class OracleConnectionPoolPolicy : IPolicy<DbConnection> {
 | 
			
		||||
 | 
			
		||||
		internal OracleConnectionPool _pool;
 | 
			
		||||
		public string Name { get; set; } = "Oracle Connection 对象池";
 | 
			
		||||
 
 | 
			
		||||
@@ -11,7 +11,7 @@ using System.Threading.Tasks;
 | 
			
		||||
 | 
			
		||||
namespace FreeSql.PostgreSQL {
 | 
			
		||||
 | 
			
		||||
	public class PostgreSQLConnectionPool : ObjectPool<DbConnection> {
 | 
			
		||||
	class PostgreSQLConnectionPool : ObjectPool<DbConnection> {
 | 
			
		||||
 | 
			
		||||
		internal Action availableHandler;
 | 
			
		||||
		internal Action unavailableHandler;
 | 
			
		||||
@@ -44,7 +44,7 @@ namespace FreeSql.PostgreSQL {
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	public class PostgreSQLConnectionPoolPolicy : IPolicy<DbConnection> {
 | 
			
		||||
	class PostgreSQLConnectionPoolPolicy : IPolicy<DbConnection> {
 | 
			
		||||
 | 
			
		||||
		internal PostgreSQLConnectionPool _pool;
 | 
			
		||||
		public string Name { get; set; } = "PostgreSQL NpgsqlConnection 对象池";
 | 
			
		||||
 
 | 
			
		||||
		Reference in New Issue
	
	Block a user