This commit is contained in:
28810 2019-02-15 17:49:01 +08:00
parent 84449e57f3
commit 2ca55c3d15
18 changed files with 403 additions and 396 deletions

View 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; }
}
}

View File

@ -7,15 +7,14 @@
<ItemGroup> <ItemGroup>
<PackageReference Include="Microsoft.AspNetCore.App" /> <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" Version="4.0.1" />
<PackageReference Include="Swashbuckle.AspNetCore.Annotations" Version="4.0.1" /> <PackageReference Include="Swashbuckle.AspNetCore.Annotations" Version="4.0.1" />
<PackageReference Include="System.Text.Encoding.CodePages" Version="4.5.1" /> <PackageReference Include="System.Text.Encoding.CodePages" Version="4.5.1" />
</ItemGroup> </ItemGroup>
<ItemGroup> <ItemGroup>
<ProjectReference Include="..\FreeSql\FreeSql.csproj" /> <ProjectReference Include="..\..\FreeSql.Extensions.EFCoreModelBuilder\FreeSql.Extensions.EFCoreModelBuilder.csproj" />
<ProjectReference Include="..\..\FreeSql\FreeSql.csproj" />
</ItemGroup> </ItemGroup>
</Project> </Project>

View 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/"
}
}
}

View File

@ -1,22 +1,14 @@
using System; using Microsoft.AspNetCore.Builder;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using Microsoft.AspNetCore.Builder;
using Microsoft.AspNetCore.Hosting; using Microsoft.AspNetCore.Hosting;
using Microsoft.AspNetCore.HttpsPolicy;
using Microsoft.AspNetCore.Mvc;
using Microsoft.EntityFrameworkCore.Metadata.Builders;
using Microsoft.Extensions.Configuration; using Microsoft.Extensions.Configuration;
using Microsoft.Extensions.DependencyInjection; using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Logging; using Microsoft.Extensions.Logging;
using Microsoft.Extensions.Options;
using Swashbuckle.AspNetCore.Swagger; using Swashbuckle.AspNetCore.Swagger;
using System;
using System.Text;
namespace FreeSql.RESTful.Demo namespace FreeSql.RESTful.Demo {
{ public class Startup
public class Startup
{ {
public Startup(IConfiguration configuration, ILoggerFactory loggerFactory) public Startup(IConfiguration configuration, ILoggerFactory loggerFactory)
{ {

View File

@ -1,64 +1,67 @@
using Microsoft.EntityFrameworkCore; using FreeSql;
using Microsoft.EntityFrameworkCore;
using Microsoft.EntityFrameworkCore.Metadata;
using System; using System;
using System.Linq; 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) {
var relationalTableName = type.FindAnnotation("Relational:TableName"); a.Name(relationalTableName.Value?.ToString() ?? type.ClrType.Name);
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);
}
}
}
});
} }
}
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);
}
}
}
});
} }
} }
}

View File

@ -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; }
}
}

View File

@ -12,14 +12,14 @@ Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Docs", "Docs", "{C6A74E2A-6
readme.md = readme.md readme.md = readme.md
EndProjectSection EndProjectSection
EndProject 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}" Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "FreeSql.Tests.PerformanceTests", "FreeSql.Tests.PerformanceTests\FreeSql.Tests.PerformanceTests.csproj", "{446D9CBE-BFE4-4FB3-ADFD-4C1C5EA1B6EE}"
EndProject 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}" Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "FreeSql.Extensions.EFCoreModelBuilder", "FreeSql.Extensions.EFCoreModelBuilder\FreeSql.Extensions.EFCoreModelBuilder.csproj", "{490CC8AF-C47C-4139-AED7-4FB6502F622B}"
EndProject 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 Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution GlobalSection(SolutionConfigurationPlatforms) = preSolution
Debug|Any CPU = Debug|Any CPU 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|x64.Build.0 = Release|Any CPU
{AA88EB04-4788-4180-AE68-7FA5ED17D98C}.Release|x86.ActiveCfg = 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 {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.ActiveCfg = Debug|Any CPU
{446D9CBE-BFE4-4FB3-ADFD-4C1C5EA1B6EE}.Debug|Any CPU.Build.0 = 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 {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|x64.Build.0 = Release|Any CPU
{446D9CBE-BFE4-4FB3-ADFD-4C1C5EA1B6EE}.Release|x86.ActiveCfg = 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 {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.ActiveCfg = Debug|Any CPU
{490CC8AF-C47C-4139-AED7-4FB6502F622B}.Debug|Any CPU.Build.0 = 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 {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|x64.Build.0 = Release|Any CPU
{490CC8AF-C47C-4139-AED7-4FB6502F622B}.Release|x86.ActiveCfg = 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 {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 EndGlobalSection
GlobalSection(SolutionProperties) = preSolution GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE HideSolutionNode = FALSE
EndGlobalSection EndGlobalSection
GlobalSection(NestedProjects) = preSolution
{C32C7D4A-76D2-4A43-9A41-4B0440819954} = {94C8A78D-AA15-47B2-A348-530CD86BFC1B}
EndGlobalSection
GlobalSection(ExtensibilityGlobals) = postSolution GlobalSection(ExtensibilityGlobals) = postSolution
SolutionGuid = {089687FD-5D25-40AB-BA8A-A10D1E137F98} SolutionGuid = {089687FD-5D25-40AB-BA8A-A10D1E137F98}
EndGlobalSection EndGlobalSection

View File

@ -41,7 +41,3 @@
public static string FormatSqlite (this string that, params object[] args) => _sqliteAdo.Addslashes(that, args); public static string FormatSqlite (this string that, params object[] args) => _sqliteAdo.Addslashes(that, args);
static FreeSql.Sqlite.SqliteAdo _sqliteAdo = new FreeSql.Sqlite.SqliteAdo(); static FreeSql.Sqlite.SqliteAdo _sqliteAdo = new FreeSql.Sqlite.SqliteAdo();
} }
namespace System.Runtime.CompilerServices {
public class ExtensionAttribute : Attribute { }
}

View File

@ -34,16 +34,20 @@ namespace FreeSql.Internal {
ConcurrentDictionary<Type, TableAttribute> dicConfigEntity = new ConcurrentDictionary<Type, TableAttribute>(); ConcurrentDictionary<Type, TableAttribute> dicConfigEntity = new ConcurrentDictionary<Type, TableAttribute>();
internal ICodeFirst ConfigEntity<T>(Action<TableFluent<T>> entity) { internal ICodeFirst ConfigEntity<T>(Action<TableFluent<T>> entity) {
if (entity == null) return _orm.CodeFirst;
var type = typeof(T); var type = typeof(T);
var table = dicConfigEntity.GetOrAdd(type, new TableAttribute()); var table = dicConfigEntity.GetOrAdd(type, new TableAttribute());
var fluent = new TableFluent<T>(table); var fluent = new TableFluent<T>(table);
entity?.Invoke(fluent); entity.Invoke(fluent);
Utils.GetTableByEntity(type, this, true); //update cache
return _orm.CodeFirst; return _orm.CodeFirst;
} }
internal ICodeFirst ConfigEntity(Type type, Action<TableFluent> entity) { internal ICodeFirst ConfigEntity(Type type, Action<TableFluent> entity) {
if (entity == null) return _orm.CodeFirst;
var table = dicConfigEntity.GetOrAdd(type, new TableAttribute()); var table = dicConfigEntity.GetOrAdd(type, new TableAttribute());
var fluent = new TableFluent(type, table); var fluent = new TableFluent(type, table);
entity?.Invoke(fluent); entity.Invoke(fluent);
Utils.GetTableByEntity(type, this, true); //update cache
return _orm.CodeFirst; return _orm.CodeFirst;
} }
internal TableAttribute GetEntityTableAttribute(Type type) { internal TableAttribute GetEntityTableAttribute(Type type) {

View File

@ -24,10 +24,10 @@ namespace FreeSql.Internal {
class Utils { class Utils {
static ConcurrentDictionary<string, ConcurrentDictionary<Type, TableInfo>> _cacheGetTableByEntity = new ConcurrentDictionary<string, ConcurrentDictionary<Type, TableInfo>>(); 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; if (entity.FullName.StartsWith("<>f__AnonymousType")) return null;
var tbc = _cacheGetTableByEntity.GetOrAdd(common.DbName, k1 => new ConcurrentDictionary<Type, TableInfo>()); //区分数据库类型缓存 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; if (common.CodeFirst.GetDbInfo(entity) != null) return null;
var tbattr = common.GetEntityTableAttribute(entity); var tbattr = common.GetEntityTableAttribute(entity);
@ -105,7 +105,7 @@ namespace FreeSql.Internal {
foreach (var col in trytb.Primarys) foreach (var col in trytb.Primarys)
col.Attribute.IsPrimary = true; col.Attribute.IsPrimary = true;
} }
tbc.TryAdd(entity, trytb); tbc.AddOrUpdate(entity, trytb, (oldkey, oldval) => trytb);
#region virtual #region virtual
if (common.CodeFirst.IsLazyLoading && propsLazy.Any()) { if (common.CodeFirst.IsLazyLoading && propsLazy.Any()) {

View File

@ -1,280 +1,280 @@
using FreeSql.DataAnnotations; //using FreeSql.DataAnnotations;
using FreeSql.Internal.Model; //using FreeSql.Internal.Model;
using Newtonsoft.Json.Linq; //using Newtonsoft.Json.Linq;
using Npgsql.LegacyPostgis; //using Npgsql.LegacyPostgis;
using NpgsqlTypes; //using NpgsqlTypes;
using System; //using System;
using System.Collections; //using System.Collections;
using System.Collections.Concurrent; //using System.Collections.Concurrent;
using System.Collections.Generic; //using System.Collections.Generic;
using System.Diagnostics; //using System.Diagnostics;
using System.Linq; //using System.Linq;
using System.Net; //using System.Net;
using System.Net.NetworkInformation; //using System.Net.NetworkInformation;
using System.Reflection; //using System.Reflection;
using System.Text.RegularExpressions; //using System.Text.RegularExpressions;
using System.Threading; //using System.Threading;
namespace FreeSql.Internal { //namespace FreeSql.Internal {
class UtilsReflection { // class UtilsReflection {
static ConcurrentDictionary<string, TableInfo> _cacheGetTableByEntity = new ConcurrentDictionary<string, TableInfo>(); // static ConcurrentDictionary<string, TableInfo> _cacheGetTableByEntity = new ConcurrentDictionary<string, TableInfo>();
internal static TableInfo GetTableByEntity(Type entity, CommonUtils common) { // internal static TableInfo GetTableByEntity(Type entity, CommonUtils common) {
if (entity.FullName.StartsWith("<>f__AnonymousType")) return null; // if (entity.FullName.StartsWith("<>f__AnonymousType")) return null;
if (_cacheGetTableByEntity.TryGetValue($"{common.DbName}-{entity.FullName}", out var trytb)) return trytb; //区分数据库类型缓存 // if (_cacheGetTableByEntity.TryGetValue($"{common.DbName}-{entity.FullName}", out var trytb)) return trytb; //区分数据库类型缓存
if (common.CodeFirst.GetDbInfo(entity) != null) return null; // if (common.CodeFirst.GetDbInfo(entity) != null) return null;
var tbattr = entity.GetCustomAttributes(typeof(TableAttribute), false).LastOrDefault() as TableAttribute; // var tbattr = entity.GetCustomAttributes(typeof(TableAttribute), false).LastOrDefault() as TableAttribute;
trytb = new TableInfo(); // trytb = new TableInfo();
trytb.Type = entity; // trytb.Type = entity;
trytb.Properties = entity.GetProperties().ToDictionary(a => a.Name, a => a, StringComparer.CurrentCultureIgnoreCase); // trytb.Properties = entity.GetProperties().ToDictionary(a => a.Name, a => a, StringComparer.CurrentCultureIgnoreCase);
trytb.CsName = entity.Name; // trytb.CsName = entity.Name;
trytb.DbName = (tbattr?.Name ?? entity.Name); // trytb.DbName = (tbattr?.Name ?? entity.Name);
trytb.DbOldName = tbattr?.OldName; // trytb.DbOldName = tbattr?.OldName;
if (common.CodeFirst.IsSyncStructureToLower) { // if (common.CodeFirst.IsSyncStructureToLower) {
trytb.DbName = trytb.DbName.ToLower(); // trytb.DbName = trytb.DbName.ToLower();
trytb.DbOldName = trytb.DbOldName?.ToLower(); // trytb.DbOldName = trytb.DbOldName?.ToLower();
} // }
trytb.SelectFilter = tbattr?.SelectFilter; // trytb.SelectFilter = tbattr?.SelectFilter;
foreach (var p in trytb.Properties.Values) { // foreach (var p in trytb.Properties.Values) {
var tp = common.CodeFirst.GetDbInfo(p.PropertyType); // var tp = common.CodeFirst.GetDbInfo(p.PropertyType);
//if (tp == null) continue; // //if (tp == null) continue;
var colattr = p.GetCustomAttributes(typeof(ColumnAttribute), false).LastOrDefault() as ColumnAttribute; // var colattr = p.GetCustomAttributes(typeof(ColumnAttribute), false).LastOrDefault() as ColumnAttribute;
if (tp == null && colattr == null) continue; // if (tp == null && colattr == null) continue;
if (colattr == null) // if (colattr == null)
colattr = new ColumnAttribute { // colattr = new ColumnAttribute {
Name = p.Name, // Name = p.Name,
DbType = tp.Value.dbtypeFull, // DbType = tp.Value.dbtypeFull,
IsIdentity = false, // IsIdentity = false,
IsNullable = tp.Value.isnullable ?? true, // IsNullable = tp.Value.isnullable ?? true,
IsPrimary = false, // IsPrimary = false,
}; // };
if (string.IsNullOrEmpty(colattr.DbType)) colattr.DbType = tp?.dbtypeFull ?? "varchar(255)"; // if (string.IsNullOrEmpty(colattr.DbType)) colattr.DbType = tp?.dbtypeFull ?? "varchar(255)";
colattr.DbType = colattr.DbType.ToUpper(); // colattr.DbType = colattr.DbType.ToUpper();
if (tp != null && tp.Value.isnullable == null) colattr.IsNullable = tp.Value.dbtypeFull.Contains("NOT NULL") == false; // 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 (colattr.DbType?.Contains("NOT NULL") == true) colattr.IsNullable = false;
if (string.IsNullOrEmpty(colattr.Name)) colattr.Name = p.Name; // if (string.IsNullOrEmpty(colattr.Name)) colattr.Name = p.Name;
if (common.CodeFirst.IsSyncStructureToLower) colattr.Name = colattr.Name.ToLower(); // 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) { // if ((colattr.IsNullable != true || colattr.IsIdentity == true || colattr.IsPrimary == true) && colattr.DbType.Contains("NOT NULL") == false) {
colattr.IsNullable = false; // colattr.IsNullable = false;
colattr.DbType += " NOT NULL"; // colattr.DbType += " NOT NULL";
} // }
if (colattr.IsNullable == true && colattr.DbType.Contains("NOT NULL")) colattr.DbType = colattr.DbType.Replace("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 => { // colattr.DbType = Regex.Replace(colattr.DbType, @"\([^\)]+\)", m => {
var tmpLt = Regex.Replace(m.Groups[0].Value, @"\s", ""); // var tmpLt = Regex.Replace(m.Groups[0].Value, @"\s", "");
if (tmpLt.Contains("CHAR")) tmpLt = tmpLt.Replace("CHAR", " CHAR"); // if (tmpLt.Contains("CHAR")) tmpLt = tmpLt.Replace("CHAR", " CHAR");
if (tmpLt.Contains("BYTE")) tmpLt = tmpLt.Replace("BYTE", " BYTE"); // if (tmpLt.Contains("BYTE")) tmpLt = tmpLt.Replace("BYTE", " BYTE");
return tmpLt; // return tmpLt;
}); // });
colattr.DbDefautValue = trytb.Properties[p.Name].GetValue(Activator.CreateInstance(trytb.Type)); // colattr.DbDefautValue = trytb.Properties[p.Name].GetValue(Activator.CreateInstance(trytb.Type));
if (colattr.DbDefautValue == null) colattr.DbDefautValue = tp?.defaultValue; // if (colattr.DbDefautValue == null) colattr.DbDefautValue = tp?.defaultValue;
if (colattr.IsNullable == false && colattr.DbDefautValue == null) // if (colattr.IsNullable == false && colattr.DbDefautValue == null)
colattr.DbDefautValue = Activator.CreateInstance(p.PropertyType.IsNullableType() ? p.PropertyType.GenericTypeArguments.FirstOrDefault() : p.PropertyType); // colattr.DbDefautValue = Activator.CreateInstance(p.PropertyType.IsNullableType() ? p.PropertyType.GenericTypeArguments.FirstOrDefault() : p.PropertyType);
var col = new ColumnInfo { // var col = new ColumnInfo {
Table = trytb, // Table = trytb,
CsName = p.Name, // CsName = p.Name,
CsType = p.PropertyType, // CsType = p.PropertyType,
Attribute = colattr // Attribute = colattr
}; // };
trytb.Columns.Add(colattr.Name, col); // trytb.Columns.Add(colattr.Name, col);
trytb.ColumnsByCs.Add(p.Name, col); // trytb.ColumnsByCs.Add(p.Name, col);
} // }
trytb.Primarys = trytb.Columns.Values.Where(a => a.Attribute.IsPrimary == true).ToArray(); // trytb.Primarys = trytb.Columns.Values.Where(a => a.Attribute.IsPrimary == true).ToArray();
if (trytb.Primarys.Any() == false) { // if (trytb.Primarys.Any() == false) {
trytb.Primarys = trytb.Columns.Values.Where(a => a.Attribute.IsIdentity == true).ToArray(); // trytb.Primarys = trytb.Columns.Values.Where(a => a.Attribute.IsIdentity == true).ToArray();
foreach(var col in trytb.Primarys) // foreach(var col in trytb.Primarys)
col.Attribute.IsPrimary = true; // col.Attribute.IsPrimary = true;
} // }
_cacheGetTableByEntity.TryAdd(entity.FullName, trytb); // _cacheGetTableByEntity.TryAdd(entity.FullName, trytb);
return trytb; // return trytb;
} // }
internal static T[] GetDbParamtersByObject<T>(string sql, object obj, string paramPrefix, Func<string, Type, object, T> constructorParamter) { // 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]; // if (string.IsNullOrEmpty(sql) || obj == null) return new T[0];
var ttype = typeof(T); // var ttype = typeof(T);
var type = obj.GetType(); // var type = obj.GetType();
if (type == ttype) return new[] { (T)Convert.ChangeType(obj, type) }; // if (type == ttype) return new[] { (T)Convert.ChangeType(obj, type) };
var ret = new List<T>(); // var ret = new List<T>();
var ps = type.GetProperties(); // var ps = type.GetProperties();
foreach (var p in ps) { // foreach (var p in ps) {
if (sql.IndexOf($"{paramPrefix}{p.Name}", StringComparison.CurrentCultureIgnoreCase) == -1) continue; // if (sql.IndexOf($"{paramPrefix}{p.Name}", StringComparison.CurrentCultureIgnoreCase) == -1) continue;
var pvalue = p.GetValue(obj); // var pvalue = p.GetValue(obj);
if (p.PropertyType == ttype) ret.Add((T)Convert.ChangeType(pvalue, ttype)); // if (p.PropertyType == ttype) ret.Add((T)Convert.ChangeType(pvalue, ttype));
else ret.Add(constructorParamter(p.Name, p.PropertyType, pvalue)); // else ret.Add(constructorParamter(p.Name, p.PropertyType, pvalue));
} // }
return ret.ToArray(); // return ret.ToArray();
} // }
static Dictionary<Type, bool> dicExecuteArrayRowReadClassOrTuple = new Dictionary<Type, bool> { // static Dictionary<Type, bool> dicExecuteArrayRowReadClassOrTuple = new Dictionary<Type, bool> {
[typeof(bool)] = true, // [typeof(bool)] = true,
[typeof(sbyte)] = true, // [typeof(sbyte)] = true,
[typeof(short)] = true, // [typeof(short)] = true,
[typeof(int)] = true, // [typeof(int)] = true,
[typeof(long)] = true, // [typeof(long)] = true,
[typeof(byte)] = true, // [typeof(byte)] = true,
[typeof(ushort)] = true, // [typeof(ushort)] = true,
[typeof(uint)] = true, // [typeof(uint)] = true,
[typeof(ulong)] = true, // [typeof(ulong)] = true,
[typeof(double)] = true, // [typeof(double)] = true,
[typeof(float)] = true, // [typeof(float)] = true,
[typeof(decimal)] = true, // [typeof(decimal)] = true,
[typeof(TimeSpan)] = true, // [typeof(TimeSpan)] = true,
[typeof(DateTime)] = true, // [typeof(DateTime)] = true,
[typeof(DateTimeOffset)] = true, // [typeof(DateTimeOffset)] = true,
[typeof(byte[])] = true, // [typeof(byte[])] = true,
[typeof(string)] = true, // [typeof(string)] = true,
[typeof(Guid)] = true, // [typeof(Guid)] = true,
[typeof(MygisPoint)] = true, // [typeof(MygisPoint)] = true,
[typeof(MygisLineString)] = true, // [typeof(MygisLineString)] = true,
[typeof(MygisPolygon)] = true, // [typeof(MygisPolygon)] = true,
[typeof(MygisMultiPoint)] = true, // [typeof(MygisMultiPoint)] = true,
[typeof(MygisMultiLineString)] = true, // [typeof(MygisMultiLineString)] = true,
[typeof(MygisMultiPolygon)] = true, // [typeof(MygisMultiPolygon)] = true,
[typeof(BitArray)] = true, // [typeof(BitArray)] = true,
[typeof(NpgsqlPoint)] = true, // [typeof(NpgsqlPoint)] = true,
[typeof(NpgsqlLine)] = true, // [typeof(NpgsqlLine)] = true,
[typeof(NpgsqlLSeg)] = true, // [typeof(NpgsqlLSeg)] = true,
[typeof(NpgsqlBox)] = true, // [typeof(NpgsqlBox)] = true,
[typeof(NpgsqlPath)] = true, // [typeof(NpgsqlPath)] = true,
[typeof(NpgsqlPolygon)] = true, // [typeof(NpgsqlPolygon)] = true,
[typeof(NpgsqlCircle)] = true, // [typeof(NpgsqlCircle)] = true,
[typeof((IPAddress Address, int Subnet))] = true, // [typeof((IPAddress Address, int Subnet))] = true,
[typeof(IPAddress)] = true, // [typeof(IPAddress)] = true,
[typeof(PhysicalAddress)] = true, // [typeof(PhysicalAddress)] = true,
[typeof(NpgsqlRange<int>)] = true, // [typeof(NpgsqlRange<int>)] = true,
[typeof(NpgsqlRange<long>)] = true, // [typeof(NpgsqlRange<long>)] = true,
[typeof(NpgsqlRange<decimal>)] = true, // [typeof(NpgsqlRange<decimal>)] = true,
[typeof(NpgsqlRange<DateTime>)] = true, // [typeof(NpgsqlRange<DateTime>)] = true,
[typeof(PostgisPoint)] = true, // [typeof(PostgisPoint)] = true,
[typeof(PostgisLineString)] = true, // [typeof(PostgisLineString)] = true,
[typeof(PostgisPolygon)] = true, // [typeof(PostgisPolygon)] = true,
[typeof(PostgisMultiPoint)] = true, // [typeof(PostgisMultiPoint)] = true,
[typeof(PostgisMultiLineString)] = true, // [typeof(PostgisMultiLineString)] = true,
[typeof(PostgisMultiPolygon)] = true, // [typeof(PostgisMultiPolygon)] = true,
[typeof(PostgisGeometry)] = true, // [typeof(PostgisGeometry)] = true,
[typeof(PostgisGeometryCollection)] = true, // [typeof(PostgisGeometryCollection)] = true,
[typeof(Dictionary<string, string>)] = true, // [typeof(Dictionary<string, string>)] = true,
[typeof(JToken)] = true, // [typeof(JToken)] = true,
[typeof(JObject)] = true, // [typeof(JObject)] = true,
[typeof(JArray)] = true, // [typeof(JArray)] = true,
}; // };
internal static ConcurrentDictionary<Type, _dicClassConstructorInfo> _dicClassConstructor = new ConcurrentDictionary<Type, _dicClassConstructorInfo>(); // internal static ConcurrentDictionary<Type, _dicClassConstructorInfo> _dicClassConstructor = new ConcurrentDictionary<Type, _dicClassConstructorInfo>();
internal static ConcurrentDictionary<Type, _dicTupleConstructorInfo> _dicTupleConstructor = new ConcurrentDictionary<Type, _dicTupleConstructorInfo>(); // internal static ConcurrentDictionary<Type, _dicTupleConstructorInfo> _dicTupleConstructor = new ConcurrentDictionary<Type, _dicTupleConstructorInfo>();
internal class _dicClassConstructorInfo { // internal class _dicClassConstructorInfo {
public ConstructorInfo Constructor { get; set; } // public ConstructorInfo Constructor { get; set; }
public PropertyInfo[] Properties { get; set; } // public PropertyInfo[] Properties { get; set; }
} // }
internal class _dicTupleConstructorInfo { // internal class _dicTupleConstructorInfo {
public ConstructorInfo Constructor { get; set; } // public ConstructorInfo Constructor { get; set; }
public Type[] Types { 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) { // 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); // if (type.IsArray) return (GetDataReaderValue(type, row[dataIndex]), dataIndex + 1);
var typeGeneric = type; // var typeGeneric = type;
if (typeGeneric.IsNullableType()) typeGeneric = type.GenericTypeArguments.First(); // if (typeGeneric.IsNullableType()) typeGeneric = type.GenericTypeArguments.First();
if (typeGeneric.IsEnum || // if (typeGeneric.IsEnum ||
dicExecuteArrayRowReadClassOrTuple.ContainsKey(typeGeneric)) // dicExecuteArrayRowReadClassOrTuple.ContainsKey(typeGeneric))
return (GetDataReaderValue(type, row[dataIndex]), dataIndex + 1); // return (GetDataReaderValue(type, row[dataIndex]), dataIndex + 1);
if (type.Namespace == "System" && (type.FullName == "System.String" || type.IsValueType)) { //值类型,或者元组 // if (type.Namespace == "System" && (type.FullName == "System.String" || type.IsValueType)) { //值类型,或者元组
bool isTuple = type.Name.StartsWith("ValueTuple`"); // bool isTuple = type.Name.StartsWith("ValueTuple`");
if (isTuple) { // if (isTuple) {
if (_dicTupleConstructor.TryGetValue(type, out var tupleInfo) == false) { // if (_dicTupleConstructor.TryGetValue(type, out var tupleInfo) == false) {
var types = type.GetFields().Select(a => a.FieldType).ToArray(); // var types = type.GetFields().Select(a => a.FieldType).ToArray();
tupleInfo = new _dicTupleConstructorInfo { Constructor = type.GetConstructor(types), Types = types }; // tupleInfo = new _dicTupleConstructorInfo { Constructor = type.GetConstructor(types), Types = types };
_dicTupleConstructor.AddOrUpdate(type, tupleInfo, (t2, c2) => tupleInfo); // _dicTupleConstructor.AddOrUpdate(type, tupleInfo, (t2, c2) => tupleInfo);
} // }
var parms = new object[tupleInfo.Types.Length]; // var parms = new object[tupleInfo.Types.Length];
for (int a = 0; a < parms.Length; a++) { // for (int a = 0; a < parms.Length; a++) {
var read = ExecuteArrayRowReadClassOrTuple(tupleInfo.Types[a], names, row, dataIndex); // var read = ExecuteArrayRowReadClassOrTuple(tupleInfo.Types[a], names, row, dataIndex);
if (read.dataIndex > dataIndex) dataIndex = read.dataIndex; // if (read.dataIndex > dataIndex) dataIndex = read.dataIndex;
parms[a] = read.value; // parms[a] = read.value;
} // }
return (tupleInfo.Constructor?.Invoke(parms), dataIndex); // return (tupleInfo.Constructor?.Invoke(parms), dataIndex);
} // }
return (dataIndex >= row.Length || (row[dataIndex] ?? DBNull.Value) == DBNull.Value ? null : GetDataReaderValue(type, row[dataIndex]), dataIndex + 1); // return (dataIndex >= row.Length || (row[dataIndex] ?? DBNull.Value) == DBNull.Value ? null : GetDataReaderValue(type, row[dataIndex]), dataIndex + 1);
} // }
if (type == typeof(object) && names != null) { // if (type == typeof(object) && names != null) {
dynamic expando = new System.Dynamic.ExpandoObject(); //动态类型字段 可读可写 // dynamic expando = new System.Dynamic.ExpandoObject(); //动态类型字段 可读可写
var expandodic = (IDictionary<string, object>)expando; // var expandodic = (IDictionary<string, object>)expando;
foreach (var name in names) // foreach (var name in names)
expandodic.Add(name.Key, row[name.Value]); // expandodic.Add(name.Key, row[name.Value]);
return (expando, names.Count); // return (expando, names.Count);
} // }
//类注入属性 // //类注入属性
if (_dicClassConstructor.TryGetValue(type, out var classInfo)== false) { // if (_dicClassConstructor.TryGetValue(type, out var classInfo)== false) {
classInfo = new _dicClassConstructorInfo { Constructor = type.GetConstructor(new Type[0]), Properties = type.GetProperties() }; // classInfo = new _dicClassConstructorInfo { Constructor = type.GetConstructor(new Type[0]), Properties = type.GetProperties() };
_dicClassConstructor.TryAdd(type, classInfo); // _dicClassConstructor.TryAdd(type, classInfo);
} // }
var value = classInfo.Constructor.Invoke(new object[0]); // var value = classInfo.Constructor.Invoke(new object[0]);
foreach(var prop in classInfo.Properties) { // foreach(var prop in classInfo.Properties) {
var tryidx = dataIndex; // var tryidx = dataIndex;
if (names != null && names.TryGetValue(prop.Name, out tryidx) == false) continue; // if (names != null && names.TryGetValue(prop.Name, out tryidx) == false) continue;
var read = ExecuteArrayRowReadClassOrTuple(prop.PropertyType, names, row, tryidx); // var read = ExecuteArrayRowReadClassOrTuple(prop.PropertyType, names, row, tryidx);
if (read.dataIndex > dataIndex) dataIndex = read.dataIndex; // if (read.dataIndex > dataIndex) dataIndex = read.dataIndex;
prop.SetValue(value, read.value, null); // prop.SetValue(value, read.value, null);
//FillPropertyValue(value, p.Name, read.value); // //FillPropertyValue(value, p.Name, read.value);
//p.SetValue(value, read.value); // //p.SetValue(value, read.value);
} // }
return (value, dataIndex); // return (value, dataIndex);
} // }
internal static void FillPropertyValue(object info, string memberAccessPath, object value) { // internal static void FillPropertyValue(object info, string memberAccessPath, object value) {
var current = info; // var current = info;
PropertyInfo prop = null; // PropertyInfo prop = null;
var members = memberAccessPath.Split('.'); // var members = memberAccessPath.Split('.');
for (var a = 0; a < members.Length; a++) { // for (var a = 0; a < members.Length; a++) {
var type = current.GetType(); // var type = current.GetType();
prop = type.GetProperty(members[a], BindingFlags.Public | BindingFlags.IgnoreCase | BindingFlags.Instance); // prop = type.GetProperty(members[a], BindingFlags.Public | BindingFlags.IgnoreCase | BindingFlags.Instance);
if (prop == null) throw new Exception(string.Concat(type.FullName, " 没有定义属性 ", members[a])); // if (prop == null) throw new Exception(string.Concat(type.FullName, " 没有定义属性 ", members[a]));
if (a < members.Length - 1) current = prop.GetValue(current); // if (a < members.Length - 1) current = prop.GetValue(current);
} // }
prop.SetValue(current, GetDataReaderValue(prop.PropertyType, value), null); // prop.SetValue(current, GetDataReaderValue(prop.PropertyType, value), null);
} // }
internal static object GetDataReaderValue(Type type, object value) { // internal static object GetDataReaderValue(Type type, object value) {
if (value == null || value == DBNull.Value) return null; // if (value == null || value == DBNull.Value) return null;
if (type.FullName == "System.Byte[]") return value; // if (type.FullName == "System.Byte[]") return value;
if (type.IsArray) { // if (type.IsArray) {
var elementType = type.GetElementType(); // var elementType = type.GetElementType();
var valueArr = value as Array; // var valueArr = value as Array;
if (elementType == valueArr.GetType().GetElementType()) return value; // if (elementType == valueArr.GetType().GetElementType()) return value;
var len = valueArr.GetLength(0); // var len = valueArr.GetLength(0);
var ret = Array.CreateInstance(elementType, len); // var ret = Array.CreateInstance(elementType, len);
for (var a = 0; a < len; a++) { // for (var a = 0; a < len; a++) {
var item = valueArr.GetValue(a); // var item = valueArr.GetValue(a);
ret.SetValue(GetDataReaderValue(elementType, item), a); // ret.SetValue(GetDataReaderValue(elementType, item), a);
} // }
return ret; // return ret;
} // }
if (type.IsNullableType()) type = type.GenericTypeArguments.First(); // if (type.IsNullableType()) type = type.GenericTypeArguments.First();
if (type.IsEnum) return Enum.Parse(type, string.Concat(value), true); // if (type.IsEnum) return Enum.Parse(type, string.Concat(value), true);
switch(type.FullName) { // switch(type.FullName) {
case "System.Guid": // case "System.Guid":
if (value.GetType() != type) return Guid.TryParse(string.Concat(value), out var tryguid) ? tryguid : Guid.Empty; // if (value.GetType() != type) return Guid.TryParse(string.Concat(value), out var tryguid) ? tryguid : Guid.Empty;
return value; // return value;
case "MygisPoint": return MygisPoint.Parse(string.Concat(value)) as MygisPoint; // case "MygisPoint": return MygisPoint.Parse(string.Concat(value)) as MygisPoint;
case "MygisLineString": return MygisLineString.Parse(string.Concat(value)) as MygisLineString; // case "MygisLineString": return MygisLineString.Parse(string.Concat(value)) as MygisLineString;
case "MygisPolygon": return MygisPolygon.Parse(string.Concat(value)) as MygisPolygon; // case "MygisPolygon": return MygisPolygon.Parse(string.Concat(value)) as MygisPolygon;
case "MygisMultiPoint": return MygisMultiPoint.Parse(string.Concat(value)) as MygisMultiPoint; // case "MygisMultiPoint": return MygisMultiPoint.Parse(string.Concat(value)) as MygisMultiPoint;
case "MygisMultiLineString": return MygisMultiLineString.Parse(string.Concat(value)) as MygisMultiLineString; // case "MygisMultiLineString": return MygisMultiLineString.Parse(string.Concat(value)) as MygisMultiLineString;
case "MygisMultiPolygon": return MygisMultiPolygon.Parse(string.Concat(value)) as MygisMultiPolygon; // 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.JToken": return JToken.Parse(string.Concat(value));
case "Newtonsoft.Json.Linq.JObject": return JObject.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 "Newtonsoft.Json.Linq.JArray": return JArray.Parse(string.Concat(value));
case "Npgsql.LegacyPostgis.PostgisGeometry": return value; // case "Npgsql.LegacyPostgis.PostgisGeometry": return value;
} // }
if (type != value.GetType()) { // if (type != value.GetType()) {
if (type.FullName == "System.TimeSpan") return TimeSpan.FromSeconds(double.Parse(value.ToString())); // if (type.FullName == "System.TimeSpan") return TimeSpan.FromSeconds(double.Parse(value.ToString()));
return Convert.ChangeType(value, type); // return Convert.ChangeType(value, type);
} // }
return value; // return value;
} // }
internal static string GetCsName(string name) { // internal static string GetCsName(string name) {
name = Regex.Replace(name.TrimStart('@'), @"[^\w]", "_"); // name = Regex.Replace(name.TrimStart('@'), @"[^\w]", "_");
return char.IsLetter(name, 0) ? name : string.Concat("_", name); // return char.IsLetter(name, 0) ? name : string.Concat("_", name);
} // }
} // }
} //}

View File

@ -11,7 +11,7 @@ using System.Threading.Tasks;
namespace FreeSql.Oracle { namespace FreeSql.Oracle {
public class OracleConnectionPool : ObjectPool<DbConnection> { class OracleConnectionPool : ObjectPool<DbConnection> {
internal Action availableHandler; internal Action availableHandler;
internal Action unavailableHandler; internal Action unavailableHandler;
@ -49,7 +49,7 @@ namespace FreeSql.Oracle {
} }
} }
public class OracleConnectionPoolPolicy : IPolicy<DbConnection> { class OracleConnectionPoolPolicy : IPolicy<DbConnection> {
internal OracleConnectionPool _pool; internal OracleConnectionPool _pool;
public string Name { get; set; } = "Oracle Connection 对象池"; public string Name { get; set; } = "Oracle Connection 对象池";

View File

@ -11,7 +11,7 @@ using System.Threading.Tasks;
namespace FreeSql.PostgreSQL { namespace FreeSql.PostgreSQL {
public class PostgreSQLConnectionPool : ObjectPool<DbConnection> { class PostgreSQLConnectionPool : ObjectPool<DbConnection> {
internal Action availableHandler; internal Action availableHandler;
internal Action unavailableHandler; internal Action unavailableHandler;
@ -44,7 +44,7 @@ namespace FreeSql.PostgreSQL {
} }
} }
public class PostgreSQLConnectionPoolPolicy : IPolicy<DbConnection> { class PostgreSQLConnectionPoolPolicy : IPolicy<DbConnection> {
internal PostgreSQLConnectionPool _pool; internal PostgreSQLConnectionPool _pool;
public string Name { get; set; } = "PostgreSQL NpgsqlConnection 对象池"; public string Name { get; set; } = "PostgreSQL NpgsqlConnection 对象池";