mirror of
				https://github.com/nsnail/FreeSql.git
				synced 2025-11-04 09:15:27 +08:00 
			
		
		
		
	v0.1.14
- 增加 延时属性编译错误信息; - 优化 FreeSql.Repository Autofac 泛型注入;
This commit is contained in:
		@@ -1,5 +1,6 @@
 | 
				
			|||||||
using Autofac;
 | 
					using Autofac;
 | 
				
			||||||
using Autofac.Extensions.DependencyInjection;
 | 
					using Autofac.Extensions.DependencyInjection;
 | 
				
			||||||
 | 
					using FreeSql.DataAnnotations;
 | 
				
			||||||
using Microsoft.AspNetCore.Builder;
 | 
					using Microsoft.AspNetCore.Builder;
 | 
				
			||||||
using Microsoft.AspNetCore.Hosting;
 | 
					using Microsoft.AspNetCore.Hosting;
 | 
				
			||||||
using Microsoft.Extensions.Configuration;
 | 
					using Microsoft.Extensions.Configuration;
 | 
				
			||||||
@@ -11,6 +12,77 @@ using System;
 | 
				
			|||||||
using System.Text;
 | 
					using System.Text;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
namespace repository_01 {
 | 
					namespace repository_01 {
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						public interface IBaseModel<TKey> {
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							TKey Id { get; set; }
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						/// <summary>
 | 
				
			||||||
 | 
						/// 用户密码信息
 | 
				
			||||||
 | 
						/// </summary>
 | 
				
			||||||
 | 
						public class SysUserLogOn : IBaseModel<Guid> {
 | 
				
			||||||
 | 
							[Column(IsPrimary = true)]
 | 
				
			||||||
 | 
							public Guid Id { get; set; } = Guid.NewGuid();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							public Guid SysUserId { get; set; }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							public string UserPassword { get; set; }
 | 
				
			||||||
 | 
							[Column(DbType = "varchar(100)")]
 | 
				
			||||||
 | 
							public string UserSecretkey { get; set; }
 | 
				
			||||||
 | 
							public DateTime PreviousVisitTime { get; set; } = DateTime.Now;
 | 
				
			||||||
 | 
							public DateTime LastVisitTime { get; set; } = DateTime.Now;
 | 
				
			||||||
 | 
							public int LogOnCount { get; set; }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							public virtual SysUser SysUser { get; set; }
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						public class SysUser : IBaseModel<Guid> {
 | 
				
			||||||
 | 
							[Column(IsPrimary = true)]
 | 
				
			||||||
 | 
							public Guid Id { get; set; } = Guid.NewGuid();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							[Column(DbType = "varchar(50)")]
 | 
				
			||||||
 | 
							public string AccountName { get; set; }
 | 
				
			||||||
 | 
							[Column(DbType = "varchar(50)")]
 | 
				
			||||||
 | 
							public string Name { get; set; }
 | 
				
			||||||
 | 
							public string HeadIcon { get; set; }
 | 
				
			||||||
 | 
							public Gender Gender { get; set; } = Gender.Man;
 | 
				
			||||||
 | 
							public DateTime Birthday { get; set; } = DateTime.MinValue;
 | 
				
			||||||
 | 
							[Column(DbType = "varchar(100)")]
 | 
				
			||||||
 | 
							public string MobilePhone { get; set; }
 | 
				
			||||||
 | 
							public string Email { get; set; }
 | 
				
			||||||
 | 
							public string WeChat { get; set; }
 | 
				
			||||||
 | 
							public string Description { get; set; }
 | 
				
			||||||
 | 
							public DateTime CreationTime { get; set; } = DateTime.Now;
 | 
				
			||||||
 | 
							public Guid? CreateUserId { get; set; }
 | 
				
			||||||
 | 
							public DateTime LastModifyTime { get; set; } = DateTime.Now;
 | 
				
			||||||
 | 
							public Guid? LastModifyUserId { get; set; }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							public AccountState State { get; set; } = AccountState.Normal;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						public enum Gender {
 | 
				
			||||||
 | 
							Man = 1,
 | 
				
			||||||
 | 
							Woman = 2,
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						public enum AccountState {
 | 
				
			||||||
 | 
							/// <summary>
 | 
				
			||||||
 | 
							/// 正常
 | 
				
			||||||
 | 
							/// </summary>
 | 
				
			||||||
 | 
							Normal = 1,
 | 
				
			||||||
 | 
							/// <summary>
 | 
				
			||||||
 | 
							/// 被禁用
 | 
				
			||||||
 | 
							/// </summary>
 | 
				
			||||||
 | 
							Disabled = 2,
 | 
				
			||||||
 | 
							/// <summary>
 | 
				
			||||||
 | 
							/// 已注销
 | 
				
			||||||
 | 
							/// </summary>
 | 
				
			||||||
 | 
							Closed = 3
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
	public class Startup {
 | 
						public class Startup {
 | 
				
			||||||
		public Startup(IConfiguration configuration, ILoggerFactory loggerFactory) {
 | 
							public Startup(IConfiguration configuration, ILoggerFactory loggerFactory) {
 | 
				
			||||||
			Configuration = configuration;
 | 
								Configuration = configuration;
 | 
				
			||||||
@@ -19,7 +91,14 @@ namespace repository_01 {
 | 
				
			|||||||
				.UseConnectionString(FreeSql.DataType.Sqlite, @"Data Source=|DataDirectory|\document.db;Pooling=true;Max Pool Size=10")
 | 
									.UseConnectionString(FreeSql.DataType.Sqlite, @"Data Source=|DataDirectory|\document.db;Pooling=true;Max Pool Size=10")
 | 
				
			||||||
				.UseLogger(loggerFactory.CreateLogger<IFreeSql>())
 | 
									.UseLogger(loggerFactory.CreateLogger<IFreeSql>())
 | 
				
			||||||
				.UseAutoSyncStructure(true)
 | 
									.UseAutoSyncStructure(true)
 | 
				
			||||||
 | 
									.UseLazyLoading(true)
 | 
				
			||||||
				.Build();
 | 
									.Build();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
								var sysu = new SysUser { };
 | 
				
			||||||
 | 
								Fsql.Insert<SysUser>().AppendData(sysu).ExecuteAffrows();
 | 
				
			||||||
 | 
								Fsql.Insert<SysUserLogOn>().AppendData(new SysUserLogOn { SysUserId = sysu.Id }).ExecuteAffrows();
 | 
				
			||||||
 | 
								var a = Fsql.Select<SysUserLogOn>().ToList();
 | 
				
			||||||
 | 
								var b = Fsql.Select<SysUserLogOn>().Any();
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		public IConfiguration Configuration { get; }
 | 
							public IConfiguration Configuration { get; }
 | 
				
			||||||
@@ -41,8 +120,8 @@ namespace repository_01 {
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
			var builder = new ContainerBuilder();
 | 
								var builder = new ContainerBuilder();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
			builder.RegisterFreeRepository<Song>(a => a.Id == 1);
 | 
								builder.RegisterFreeRepositoryAddFilter<Song>(() => a => a.Title == DateTime.Now.ToString() + System.Threading.Thread.CurrentThread.ManagedThreadId);
 | 
				
			||||||
			builder.RegisterFreeGuidRepository<Song>(a => a.Id == 1, oldname => $"{oldname}_{DateTime.Now.Year}");
 | 
								//builder.RegisterFreeGuidRepository<Song>(a => a.Id == 1, oldname => $"{oldname}_{DateTime.Now.Year}");
 | 
				
			||||||
 | 
					
 | 
				
			||||||
			builder.Populate(services);
 | 
								builder.Populate(services);
 | 
				
			||||||
			var container = builder.Build();
 | 
								var container = builder.Build();
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -1,7 +1,7 @@
 | 
				
			|||||||
<Project Sdk="Microsoft.NET.Sdk.Web">
 | 
					<Project Sdk="Microsoft.NET.Sdk.Web">
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	<PropertyGroup>
 | 
						<PropertyGroup>
 | 
				
			||||||
		<TargetFramework>netcoreapp2.2</TargetFramework>
 | 
							<TargetFramework>netcoreapp2.1</TargetFramework>
 | 
				
			||||||
		<AspNetCoreHostingModel>InProcess</AspNetCoreHostingModel>
 | 
							<AspNetCoreHostingModel>InProcess</AspNetCoreHostingModel>
 | 
				
			||||||
	</PropertyGroup>
 | 
						</PropertyGroup>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -8,62 +8,123 @@ using System.Reflection;
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
public static class FreeSqlRepositoryAutofacDependencyInjection {
 | 
					public static class FreeSqlRepositoryAutofacDependencyInjection {
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	public static void RegisterFreeGuidRepository<TEntity>(this ContainerBuilder builder, Expression<Func<TEntity, bool>> filter, Func<string, string> asTable) =>
 | 
						public static void RegisterFreeRepository(this ContainerBuilder builder) => RegisterFreeRepositoryPrivate<bool>(builder, null, null);
 | 
				
			||||||
		builder.RegisterRepository<TEntity>(filter, asTable, 1);
 | 
						public static void RegisterFreeRepositoryAddFilter<TEntity>(this ContainerBuilder builder, Func<Expression<Func<TEntity, bool>>> filterHandler) => RegisterFreeRepositoryPrivate<TEntity>(builder, filterHandler, null);
 | 
				
			||||||
	public static void RegisterFreeRepository<TEntity>(this ContainerBuilder builder, Expression<Func<TEntity, bool>> filter) =>
 | 
					 | 
				
			||||||
		builder.RegisterRepository<TEntity>(filter, null, 2);
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
	static void RegisterRepository<TEntity>(this ContainerBuilder builder, Expression<Func<TEntity, bool>> filter, Func<string, string> asTable, int regType) {
 | 
						static ConcurrentDictionary<Type, Delegate> _dicRegisterFreeRepositorySetFilterFunc = new ConcurrentDictionary<Type, Delegate>();
 | 
				
			||||||
 | 
						static ConcurrentDictionary<Type, Delegate> _dicRegisterFreeRepositorySetAsTableFunc = new ConcurrentDictionary<Type, Delegate>();
 | 
				
			||||||
 | 
						static void RegisterFreeRepositoryPrivate<TEntity>(ContainerBuilder builder, Func<Expression<Func<TEntity, bool>>> filterHandler, Func<string, string> asTableHandler) {
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		Func<Type, LambdaExpression> reposFunc = type => {
 | 
							Func<Type, Delegate> setFilterFunc = reposType => _dicRegisterFreeRepositorySetFilterFunc.GetOrAdd(reposType, type => { 
 | 
				
			||||||
 | 
								var reposParameter = Expression.Parameter(type);
 | 
				
			||||||
 | 
								var fitlerParameter = Expression.Parameter(typeof(Expression<>).MakeGenericType(typeof(Func<,>).MakeGenericType(type.GenericTypeArguments[0], typeof(bool))));
 | 
				
			||||||
 | 
								return Expression.Lambda(
 | 
				
			||||||
 | 
									Expression.Block(
 | 
				
			||||||
 | 
										Expression.Call(reposParameter, type.GetMethod("set_Filter", BindingFlags.Instance | BindingFlags.NonPublic), fitlerParameter)
 | 
				
			||||||
 | 
									),
 | 
				
			||||||
 | 
									new[] {
 | 
				
			||||||
 | 
										reposParameter, fitlerParameter
 | 
				
			||||||
 | 
									}
 | 
				
			||||||
 | 
								).Compile();
 | 
				
			||||||
 | 
							});
 | 
				
			||||||
 | 
							Func<Type, LambdaExpression> convertFilter = type => {
 | 
				
			||||||
 | 
								var filter = filterHandler?.Invoke();
 | 
				
			||||||
 | 
								if (filter == null) return null;
 | 
				
			||||||
			var entityType = type.GenericTypeArguments[0];
 | 
								var entityType = type.GenericTypeArguments[0];
 | 
				
			||||||
			var filterParameter1 = Expression.Parameter(entityType, filter.Parameters[0].Name);
 | 
								var filterParameter1 = Expression.Parameter(entityType, filter.Parameters[0].Name);
 | 
				
			||||||
			var convertFilter = Expression.Lambda(
 | 
								try {
 | 
				
			||||||
				typeof(Func<,>).MakeGenericType(entityType, typeof(bool)),
 | 
									return Expression.Lambda(
 | 
				
			||||||
				new ReplaceVisitor<TEntity>().Modify(filter.Body, filterParameter1),
 | 
										typeof(Func<,>).MakeGenericType(entityType, typeof(bool)),
 | 
				
			||||||
				filterParameter1
 | 
										new ReplaceVisitor<TEntity>().Modify(filter.Body, filterParameter1),
 | 
				
			||||||
			);
 | 
										filterParameter1
 | 
				
			||||||
			var repos = Expression.Parameter(type);
 | 
									);
 | 
				
			||||||
			var blocks = new List<Expression>();
 | 
								} catch {
 | 
				
			||||||
			if (filter != null) blocks.Add(Expression.Call(repos, type.GetMethod("set_Filter", BindingFlags.Instance | BindingFlags.NonPublic), Expression.Constant(convertFilter)));
 | 
									return null;
 | 
				
			||||||
			if (asTable != null) blocks.Add(Expression.Call(repos, type.GetMethod("set_AsTable", BindingFlags.Instance | BindingFlags.NonPublic), Expression.Constant(asTable)));
 | 
								}
 | 
				
			||||||
			return Expression.Lambda(
 | 
					 | 
				
			||||||
				//Expression.New(
 | 
					 | 
				
			||||||
				//	typeof(GuidRepository<>).MakeGenericType(type.GenericTypeArguments).GetConstructors()[1],
 | 
					 | 
				
			||||||
				//	Expression.Constant(a.Context.Resolve<IFreeSql>()),
 | 
					 | 
				
			||||||
				//	Expression.Constant(convertFilter),
 | 
					 | 
				
			||||||
				//	Expression.Constant(asTable)
 | 
					 | 
				
			||||||
				//)
 | 
					 | 
				
			||||||
				Expression.Block(blocks),
 | 
					 | 
				
			||||||
				repos
 | 
					 | 
				
			||||||
			);
 | 
					 | 
				
			||||||
		};
 | 
							};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		if (regType == 1)
 | 
							builder.RegisterGeneric(typeof(GuidRepository<>)).As(
 | 
				
			||||||
			builder.RegisterGeneric(typeof(GuidRepository<>)).As(
 | 
								typeof(GuidRepository<>),
 | 
				
			||||||
				typeof(GuidRepository<>),
 | 
								typeof(BaseRepository<>),
 | 
				
			||||||
				typeof(BaseRepository<>), typeof(BaseRepository<,>),
 | 
								typeof(IBasicRepository<>),
 | 
				
			||||||
				typeof(IBasicRepository<>), typeof(IBasicRepository<,>),
 | 
								typeof(IReadOnlyRepository<>)
 | 
				
			||||||
				typeof(IReadOnlyRepository<>), typeof(IReadOnlyRepository<,>)
 | 
							).OnActivating(a => {
 | 
				
			||||||
			).OnActivating(a => {
 | 
								if (filterHandler != null) {
 | 
				
			||||||
				if (filter != null)
 | 
									var type = a.Instance.GetType();
 | 
				
			||||||
					_dicAddGuidRepositoryFunc.GetOrAdd(a.Instance.GetType(), t => reposFunc(t).Compile()).DynamicInvoke(a.Instance);
 | 
									setFilterFunc(type)?.DynamicInvoke(a.Instance, convertFilter(type));
 | 
				
			||||||
			}).InstancePerDependency();
 | 
								}
 | 
				
			||||||
 | 
							}).InstancePerDependency();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							builder.RegisterGeneric(typeof(DefaultRepository<,>)).As(
 | 
				
			||||||
		if (regType == 2)
 | 
								typeof(DefaultRepository<,>),
 | 
				
			||||||
			builder.RegisterGeneric(typeof(DefaultRepository<,>)).As(
 | 
								typeof(BaseRepository<,>),
 | 
				
			||||||
				typeof(DefaultRepository<,>),
 | 
								typeof(IBasicRepository<,>),
 | 
				
			||||||
				typeof(BaseRepository<,>),
 | 
								typeof(IReadOnlyRepository<,>)
 | 
				
			||||||
				typeof(IBasicRepository<,>),
 | 
							).OnActivating(a => {
 | 
				
			||||||
				typeof(IReadOnlyRepository<,>)
 | 
								if (filterHandler != null) {
 | 
				
			||||||
			).OnActivating(a => {
 | 
									var type = a.Instance.GetType();
 | 
				
			||||||
				if (filter != null)
 | 
									setFilterFunc(type)?.DynamicInvoke(a.Instance, convertFilter(type));
 | 
				
			||||||
					_dicAddGuidRepositoryFunc.GetOrAdd(a.Instance.GetType(), t => reposFunc(t).Compile()).DynamicInvoke(a.Instance);
 | 
								}
 | 
				
			||||||
			}).InstancePerDependency();
 | 
							}).InstancePerDependency();
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	static ConcurrentDictionary<Type, Delegate> _dicAddGuidRepositoryFunc = new ConcurrentDictionary<Type, Delegate>();
 | 
						//static void RegisterRepository<TEntity>(this ContainerBuilder builder, Expression<Func<TEntity, bool>> filter, Func<string, string> asTable, int regType) {
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						//	Func<Type, LambdaExpression> reposFunc = type => {
 | 
				
			||||||
 | 
						//		var entityType = type.GenericTypeArguments[0];
 | 
				
			||||||
 | 
						//		var filterParameter1 = Expression.Parameter(entityType, filter.Parameters[0].Name);
 | 
				
			||||||
 | 
						//		var convertFilter = Expression.Lambda(
 | 
				
			||||||
 | 
						//			typeof(Func<,>).MakeGenericType(entityType, typeof(bool)),
 | 
				
			||||||
 | 
						//			new ReplaceVisitor<TEntity>().Modify(filter.Body, filterParameter1),
 | 
				
			||||||
 | 
						//			filterParameter1
 | 
				
			||||||
 | 
						//		);
 | 
				
			||||||
 | 
						//		var repos = Expression.Parameter(type);
 | 
				
			||||||
 | 
						//		var blocks = new List<Expression>();
 | 
				
			||||||
 | 
						//		if (filter != null) blocks.Add(Expression.Call(repos, type.GetMethod("set_Filter", BindingFlags.Instance | BindingFlags.NonPublic), Expression.Constant(convertFilter)));
 | 
				
			||||||
 | 
						//		if (asTable != null) blocks.Add(Expression.Call(repos, type.GetMethod("set_AsTable", BindingFlags.Instance | BindingFlags.NonPublic), Expression.Constant(asTable)));
 | 
				
			||||||
 | 
						//		return Expression.Lambda(
 | 
				
			||||||
 | 
						//			//Expression.New(
 | 
				
			||||||
 | 
						//			//	typeof(GuidRepository<>).MakeGenericType(type.GenericTypeArguments).GetConstructors()[1],
 | 
				
			||||||
 | 
						//			//	Expression.Constant(a.Context.Resolve<IFreeSql>()),
 | 
				
			||||||
 | 
						//			//	Expression.Constant(convertFilter),
 | 
				
			||||||
 | 
						//			//	Expression.Constant(asTable)
 | 
				
			||||||
 | 
						//			//)
 | 
				
			||||||
 | 
						//			Expression.Block(blocks),
 | 
				
			||||||
 | 
						//			repos
 | 
				
			||||||
 | 
						//		);
 | 
				
			||||||
 | 
						//	};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						//	if (regType == 1)
 | 
				
			||||||
 | 
						//		builder.RegisterGeneric(typeof(GuidRepository<>)).As(
 | 
				
			||||||
 | 
						//			typeof(GuidRepository<>),
 | 
				
			||||||
 | 
						//			typeof(BaseRepository<>), typeof(BaseRepository<,>),
 | 
				
			||||||
 | 
						//			typeof(IBasicRepository<>), typeof(IBasicRepository<,>),
 | 
				
			||||||
 | 
						//			typeof(IReadOnlyRepository<>), typeof(IReadOnlyRepository<,>)
 | 
				
			||||||
 | 
						//		).OnActivating(a => {
 | 
				
			||||||
 | 
						//			if (filter != null)
 | 
				
			||||||
 | 
						//				_dicAddGuidRepositoryFunc.GetOrAdd(a.Instance.GetType(), t => {
 | 
				
			||||||
 | 
						//					try { reposFunc(t).Compile(); } catch { }
 | 
				
			||||||
 | 
						//					return null;
 | 
				
			||||||
 | 
						//				})?.DynamicInvoke(a.Instance);
 | 
				
			||||||
 | 
						//		}).InstancePerDependency();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						//	if (regType == 2)
 | 
				
			||||||
 | 
						//		builder.RegisterGeneric(typeof(DefaultRepository<,>)).As(
 | 
				
			||||||
 | 
						//			typeof(DefaultRepository<,>),
 | 
				
			||||||
 | 
						//			typeof(BaseRepository<,>),
 | 
				
			||||||
 | 
						//			typeof(IBasicRepository<,>),
 | 
				
			||||||
 | 
						//			typeof(IReadOnlyRepository<,>)
 | 
				
			||||||
 | 
						//		).OnActivating(a => {
 | 
				
			||||||
 | 
						//			if (filter != null)
 | 
				
			||||||
 | 
						//				_dicAddGuidRepositoryFunc.GetOrAdd(a.Instance.GetType(), t => {
 | 
				
			||||||
 | 
						//					try { reposFunc(t).Compile(); } catch { }
 | 
				
			||||||
 | 
						//					return null;
 | 
				
			||||||
 | 
						//				})?.DynamicInvoke(a.Instance);
 | 
				
			||||||
 | 
						//		}).InstancePerDependency();
 | 
				
			||||||
 | 
						//}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						//static ConcurrentDictionary<Type, Delegate> _dicAddGuidRepositoryFunc = new ConcurrentDictionary<Type, Delegate>();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	class ReplaceVisitor<TEntity1> : ExpressionVisitor {
 | 
						class ReplaceVisitor<TEntity1> : ExpressionVisitor {
 | 
				
			||||||
		private ParameterExpression parameter;
 | 
							private ParameterExpression parameter;
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -2,7 +2,7 @@
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
  <PropertyGroup>
 | 
					  <PropertyGroup>
 | 
				
			||||||
    <TargetFramework>netstandard2.0</TargetFramework>
 | 
					    <TargetFramework>netstandard2.0</TargetFramework>
 | 
				
			||||||
    <Version>0.1.13</Version>
 | 
					    <Version>0.1.14</Version>
 | 
				
			||||||
    <Authors>YeXiangQin</Authors>
 | 
					    <Authors>YeXiangQin</Authors>
 | 
				
			||||||
    <Description>FreeSql 通用仓库层实现,支持 MySql/SqlServer/PostgreSQL/Oracle/Sqlite,读写分离、分表分库。</Description>
 | 
					    <Description>FreeSql 通用仓库层实现,支持 MySql/SqlServer/PostgreSQL/Oracle/Sqlite,读写分离、分表分库。</Description>
 | 
				
			||||||
    <PackageProjectUrl>https://github.com/2881099/FreeSql</PackageProjectUrl>
 | 
					    <PackageProjectUrl>https://github.com/2881099/FreeSql</PackageProjectUrl>
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -2,7 +2,7 @@
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
  <PropertyGroup>
 | 
					  <PropertyGroup>
 | 
				
			||||||
    <TargetFramework>netstandard2.0</TargetFramework>
 | 
					    <TargetFramework>netstandard2.0</TargetFramework>
 | 
				
			||||||
    <Version>0.1.13</Version>
 | 
					    <Version>0.1.14</Version>
 | 
				
			||||||
    <GeneratePackageOnBuild>true</GeneratePackageOnBuild>
 | 
					    <GeneratePackageOnBuild>true</GeneratePackageOnBuild>
 | 
				
			||||||
    <Authors>YeXiangQin</Authors>
 | 
					    <Authors>YeXiangQin</Authors>
 | 
				
			||||||
    <Description>打造 .NETCore 最方便的 ORM,DbFirst 与 CodeFirst 混合使用,提供从实体同步数据库,或者从数据库生成实体代码,支持 MySql/SqlServer/PostgreSQL/Oracle/Sqlite,读写分离、分表分库。</Description>
 | 
					    <Description>打造 .NETCore 最方便的 ORM,DbFirst 与 CodeFirst 混合使用,提供从实体同步数据库,或者从数据库生成实体代码,支持 MySql/SqlServer/PostgreSQL/Oracle/Sqlite,读写分离、分表分库。</Description>
 | 
				
			||||||
@@ -20,8 +20,8 @@
 | 
				
			|||||||
    <PackageReference Include="Newtonsoft.Json" Version="12.0.1" />
 | 
					    <PackageReference Include="Newtonsoft.Json" Version="12.0.1" />
 | 
				
			||||||
    <PackageReference Include="Npgsql" Version="4.0.5" />
 | 
					    <PackageReference Include="Npgsql" Version="4.0.5" />
 | 
				
			||||||
    <PackageReference Include="Npgsql.LegacyPostgis" Version="4.0.5" />
 | 
					    <PackageReference Include="Npgsql.LegacyPostgis" Version="4.0.5" />
 | 
				
			||||||
    <PackageReference Include="Oracle.ManagedDataAccess.Core" Version="2.18.3" />
 | 
					    <PackageReference Include="Oracle.ManagedDataAccess.Core" Version="2.18.5" />
 | 
				
			||||||
    <PackageReference Include="SafeObjectPool" Version="1.0.14" />
 | 
					    <PackageReference Include="SafeObjectPool" Version="2.0.1" />
 | 
				
			||||||
    <PackageReference Include="System.Data.SqlClient" Version="4.6.0" />
 | 
					    <PackageReference Include="System.Data.SqlClient" Version="4.6.0" />
 | 
				
			||||||
    <PackageReference Include="System.Data.SQLite.Core" Version="1.0.110" />
 | 
					    <PackageReference Include="System.Data.SQLite.Core" Version="1.0.110" />
 | 
				
			||||||
    <PackageReference Include="System.Reflection.Emit.Lightweight" Version="4.3.0" />
 | 
					    <PackageReference Include="System.Reflection.Emit.Lightweight" Version="4.3.0" />
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -449,8 +449,13 @@ namespace FreeSql.Internal {
 | 
				
			|||||||
				}
 | 
									}
 | 
				
			||||||
				if (overrieds > 0) {
 | 
									if (overrieds > 0) {
 | 
				
			||||||
					cscode.AppendLine("}");
 | 
										cscode.AppendLine("}");
 | 
				
			||||||
					var assemly = Generator.TemplateEngin._compiler.Value.CompileCode(cscode.ToString());
 | 
										Assembly assembly = null;
 | 
				
			||||||
					var type = assemly.DefinedTypes.Where(a => a.FullName.EndsWith(trytbTypeLazyName)).FirstOrDefault();
 | 
										try {
 | 
				
			||||||
 | 
											assembly = Generator.TemplateEngin._compiler.Value.CompileCode(cscode.ToString());
 | 
				
			||||||
 | 
										} catch (Exception ex) {
 | 
				
			||||||
 | 
											throw new Exception($"【延时加载】{trytbTypeName} 编译错误:{ex.Message}\r\n\r\n{cscode}");
 | 
				
			||||||
 | 
										}
 | 
				
			||||||
 | 
										var type = assembly.DefinedTypes.Where(a => a.FullName.EndsWith(trytbTypeLazyName)).FirstOrDefault();
 | 
				
			||||||
					trytb.TypeLazy = type;
 | 
										trytb.TypeLazy = type;
 | 
				
			||||||
					trytb.TypeLazySetOrm = type.GetProperty("__fsql_orm__", BindingFlags.Instance | BindingFlags.NonPublic).GetSetMethod(true);
 | 
										trytb.TypeLazySetOrm = type.GetProperty("__fsql_orm__", BindingFlags.Instance | BindingFlags.NonPublic).GetSetMethod(true);
 | 
				
			||||||
				}
 | 
									}
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -41,6 +41,7 @@ namespace FreeSql.MySql {
 | 
				
			|||||||
		public string Name { get; set; } = "MySql MySqlConnection 对象池";
 | 
							public string Name { get; set; } = "MySql MySqlConnection 对象池";
 | 
				
			||||||
		public int PoolSize { get; set; } = 100;
 | 
							public int PoolSize { get; set; } = 100;
 | 
				
			||||||
		public TimeSpan SyncGetTimeout { get; set; } = TimeSpan.FromSeconds(10);
 | 
							public TimeSpan SyncGetTimeout { get; set; } = TimeSpan.FromSeconds(10);
 | 
				
			||||||
 | 
							public TimeSpan IdleTimeout { get; set; } = TimeSpan.Zero;
 | 
				
			||||||
		public int AsyncGetCapacity { get; set; } = 10000;
 | 
							public int AsyncGetCapacity { get; set; } = 10000;
 | 
				
			||||||
		public bool IsThrowGetTimeoutException { get; set; } = true;
 | 
							public bool IsThrowGetTimeoutException { get; set; } = true;
 | 
				
			||||||
		public int CheckAvailableInterval { get; set; } = 5;
 | 
							public int CheckAvailableInterval { get; set; } = 5;
 | 
				
			||||||
@@ -50,17 +51,25 @@ namespace FreeSql.MySql {
 | 
				
			|||||||
		public string ConnectionString {
 | 
							public string ConnectionString {
 | 
				
			||||||
			get => _connectionString;
 | 
								get => _connectionString;
 | 
				
			||||||
			set {
 | 
								set {
 | 
				
			||||||
				var connStr = value ?? "";
 | 
									_connectionString = value ?? "";
 | 
				
			||||||
				var poolsizePatern = @"Max\s*pool\s*size\s*=\s*(\d+)";
 | 
					
 | 
				
			||||||
				Match m = Regex.Match(connStr, poolsizePatern, RegexOptions.IgnoreCase);
 | 
									var pattern = @"Max\s*pool\s*size\s*=\s*(\d+)";
 | 
				
			||||||
 | 
									var m = Regex.Match(_connectionString, pattern, RegexOptions.IgnoreCase);
 | 
				
			||||||
				if (m.Success == false || int.TryParse(m.Groups[1].Value, out var poolsize) == false || poolsize <= 0) poolsize = 100;
 | 
									if (m.Success == false || int.TryParse(m.Groups[1].Value, out var poolsize) == false || poolsize <= 0) poolsize = 100;
 | 
				
			||||||
				var connStrIncr = dicConnStrIncr.AddOrUpdate(connStr, 1, (oldkey, oldval) => oldval + 1);
 | 
									var connStrIncr = dicConnStrIncr.AddOrUpdate(_connectionString, 1, (oldkey, oldval) => oldval + 1);
 | 
				
			||||||
				PoolSize = poolsize + connStrIncr;
 | 
									PoolSize = poolsize + connStrIncr;
 | 
				
			||||||
				_connectionString = m.Success ? 
 | 
									_connectionString = m.Success ? 
 | 
				
			||||||
					Regex.Replace(connStr, poolsizePatern, $"Max pool size={PoolSize}", RegexOptions.IgnoreCase) :
 | 
										Regex.Replace(_connectionString, pattern, $"Max pool size={PoolSize}", RegexOptions.IgnoreCase) :
 | 
				
			||||||
					$"{connStr};Max pool size={PoolSize}";
 | 
										$"{_connectionString};Max pool size={PoolSize}";
 | 
				
			||||||
 | 
					
 | 
				
			||||||
				var initConns = new List<Object<DbConnection>>();
 | 
									pattern = @"Connection\s*LifeTime\s*=\s*(\d+)";
 | 
				
			||||||
 | 
									m = Regex.Match(_connectionString, pattern, RegexOptions.IgnoreCase);
 | 
				
			||||||
 | 
									if (m.Success) {
 | 
				
			||||||
 | 
										IdleTimeout = TimeSpan.FromSeconds(int.Parse(m.Groups[1].Value));
 | 
				
			||||||
 | 
										_connectionString = Regex.Replace(_connectionString, pattern, "", RegexOptions.IgnoreCase);
 | 
				
			||||||
 | 
									}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
									 var initConns = new List<Object<DbConnection>>();
 | 
				
			||||||
				for (var a = 0; a < PoolSize; a++)
 | 
									for (var a = 0; a < PoolSize; a++)
 | 
				
			||||||
					try {
 | 
										try {
 | 
				
			||||||
						var conn = _pool.Get();
 | 
											var conn = _pool.Get();
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -55,6 +55,7 @@ namespace FreeSql.Oracle {
 | 
				
			|||||||
		public string Name { get; set; } = "Oracle Connection 对象池";
 | 
							public string Name { get; set; } = "Oracle Connection 对象池";
 | 
				
			||||||
		public int PoolSize { get; set; } = 100;
 | 
							public int PoolSize { get; set; } = 100;
 | 
				
			||||||
		public TimeSpan SyncGetTimeout { get; set; } = TimeSpan.FromSeconds(10);
 | 
							public TimeSpan SyncGetTimeout { get; set; } = TimeSpan.FromSeconds(10);
 | 
				
			||||||
 | 
							public TimeSpan IdleTimeout { get; set; } = TimeSpan.Zero;
 | 
				
			||||||
		public int AsyncGetCapacity { get; set; } = 10000;
 | 
							public int AsyncGetCapacity { get; set; } = 10000;
 | 
				
			||||||
		public bool IsThrowGetTimeoutException { get; set; } = true;
 | 
							public bool IsThrowGetTimeoutException { get; set; } = true;
 | 
				
			||||||
		public int CheckAvailableInterval { get; set; } = 5;
 | 
							public int CheckAvailableInterval { get; set; } = 5;
 | 
				
			||||||
@@ -64,15 +65,23 @@ namespace FreeSql.Oracle {
 | 
				
			|||||||
		public string ConnectionString {
 | 
							public string ConnectionString {
 | 
				
			||||||
			get => _connectionString;
 | 
								get => _connectionString;
 | 
				
			||||||
			set {
 | 
								set {
 | 
				
			||||||
				var connStr = value ?? "";
 | 
									_connectionString = value ?? "";
 | 
				
			||||||
				var poolsizePatern = @"Max\s*pool\s*size\s*=\s*(\d+)";
 | 
					
 | 
				
			||||||
				Match m = Regex.Match(connStr, poolsizePatern, RegexOptions.IgnoreCase);
 | 
									var pattern = @"Max\s*pool\s*size\s*=\s*(\d+)";
 | 
				
			||||||
 | 
									Match m = Regex.Match(_connectionString, pattern, RegexOptions.IgnoreCase);
 | 
				
			||||||
				if (m.Success == false || int.TryParse(m.Groups[1].Value, out var poolsize) == false || poolsize <= 0) poolsize = 100;
 | 
									if (m.Success == false || int.TryParse(m.Groups[1].Value, out var poolsize) == false || poolsize <= 0) poolsize = 100;
 | 
				
			||||||
				var connStrIncr = dicConnStrIncr.AddOrUpdate(connStr, 1, (oldkey, oldval) => oldval + 1);
 | 
									var connStrIncr = dicConnStrIncr.AddOrUpdate(_connectionString, 1, (oldkey, oldval) => oldval + 1);
 | 
				
			||||||
				PoolSize = poolsize + connStrIncr;
 | 
									PoolSize = poolsize + connStrIncr;
 | 
				
			||||||
				_connectionString = m.Success ?
 | 
									_connectionString = m.Success ?
 | 
				
			||||||
					Regex.Replace(connStr, poolsizePatern, $"Max pool size={PoolSize}", RegexOptions.IgnoreCase) :
 | 
										Regex.Replace(_connectionString, pattern, $"Max pool size={PoolSize}", RegexOptions.IgnoreCase) :
 | 
				
			||||||
					$"{connStr};Max pool size={PoolSize}";
 | 
										$"{_connectionString};Max pool size={PoolSize}";
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
									pattern = @"Connection\s*LifeTime\s*=\s*(\d+)";
 | 
				
			||||||
 | 
									m = Regex.Match(_connectionString, pattern, RegexOptions.IgnoreCase);
 | 
				
			||||||
 | 
									if (m.Success) {
 | 
				
			||||||
 | 
										IdleTimeout = TimeSpan.FromSeconds(int.Parse(m.Groups[1].Value));
 | 
				
			||||||
 | 
										_connectionString = Regex.Replace(_connectionString, pattern, "", RegexOptions.IgnoreCase);
 | 
				
			||||||
 | 
									}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
				var initConns = new List<Object<DbConnection>>();
 | 
									var initConns = new List<Object<DbConnection>>();
 | 
				
			||||||
				for (var a = 0; a < PoolSize; a++)
 | 
									for (var a = 0; a < PoolSize; a++)
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -50,6 +50,7 @@ namespace FreeSql.PostgreSQL {
 | 
				
			|||||||
		public string Name { get; set; } = "PostgreSQL NpgsqlConnection 对象池";
 | 
							public string Name { get; set; } = "PostgreSQL NpgsqlConnection 对象池";
 | 
				
			||||||
		public int PoolSize { get; set; } = 50;
 | 
							public int PoolSize { get; set; } = 50;
 | 
				
			||||||
		public TimeSpan SyncGetTimeout { get; set; } = TimeSpan.FromSeconds(10);
 | 
							public TimeSpan SyncGetTimeout { get; set; } = TimeSpan.FromSeconds(10);
 | 
				
			||||||
 | 
							public TimeSpan IdleTimeout { get; set; } = TimeSpan.Zero;
 | 
				
			||||||
		public int AsyncGetCapacity { get; set; } = 10000;
 | 
							public int AsyncGetCapacity { get; set; } = 10000;
 | 
				
			||||||
		public bool IsThrowGetTimeoutException { get; set; } = true;
 | 
							public bool IsThrowGetTimeoutException { get; set; } = true;
 | 
				
			||||||
		public int CheckAvailableInterval { get; set; } = 5;
 | 
							public int CheckAvailableInterval { get; set; } = 5;
 | 
				
			||||||
@@ -59,15 +60,23 @@ namespace FreeSql.PostgreSQL {
 | 
				
			|||||||
		public string ConnectionString {
 | 
							public string ConnectionString {
 | 
				
			||||||
			get => _connectionString;
 | 
								get => _connectionString;
 | 
				
			||||||
			set {
 | 
								set {
 | 
				
			||||||
				var connStr = value ?? "";
 | 
									_connectionString = value ?? "";
 | 
				
			||||||
				var poolsizePatern = @"Maximum\s*pool\s*size\s*=\s*(\d+)";
 | 
					
 | 
				
			||||||
				Match m = Regex.Match(connStr, poolsizePatern, RegexOptions.IgnoreCase);
 | 
									var pattern = @"Maximum\s*pool\s*size\s*=\s*(\d+)";
 | 
				
			||||||
 | 
									Match m = Regex.Match(_connectionString, pattern, RegexOptions.IgnoreCase);
 | 
				
			||||||
				if (m.Success == false || int.TryParse(m.Groups[1].Value, out var poolsize) == false || poolsize <= 0) poolsize = 100;
 | 
									if (m.Success == false || int.TryParse(m.Groups[1].Value, out var poolsize) == false || poolsize <= 0) poolsize = 100;
 | 
				
			||||||
				var connStrIncr = dicConnStrIncr.AddOrUpdate(connStr, 1, (oldkey, oldval) => oldval + 1);
 | 
									var connStrIncr = dicConnStrIncr.AddOrUpdate(_connectionString, 1, (oldkey, oldval) => oldval + 1);
 | 
				
			||||||
				PoolSize = poolsize + connStrIncr;
 | 
									PoolSize = poolsize + connStrIncr;
 | 
				
			||||||
				_connectionString = m.Success ?
 | 
									_connectionString = m.Success ?
 | 
				
			||||||
					Regex.Replace(connStr, poolsizePatern, $"Maximum pool size={PoolSize}", RegexOptions.IgnoreCase) :
 | 
										Regex.Replace(_connectionString, pattern, $"Maximum pool size={PoolSize}", RegexOptions.IgnoreCase) :
 | 
				
			||||||
					$"{connStr};Maximum pool size={PoolSize}";
 | 
										$"{_connectionString};Maximum pool size={PoolSize}";
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
									pattern = @"Connection\s*LifeTime\s*=\s*(\d+)";
 | 
				
			||||||
 | 
									m = Regex.Match(_connectionString, pattern, RegexOptions.IgnoreCase);
 | 
				
			||||||
 | 
									if (m.Success) {
 | 
				
			||||||
 | 
										IdleTimeout = TimeSpan.FromSeconds(int.Parse(m.Groups[1].Value));
 | 
				
			||||||
 | 
										_connectionString = Regex.Replace(_connectionString, pattern, "", RegexOptions.IgnoreCase);
 | 
				
			||||||
 | 
									}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
				var initConns = new List<Object<DbConnection>>();
 | 
									var initConns = new List<Object<DbConnection>>();
 | 
				
			||||||
				for (var a = 0; a < PoolSize; a++)
 | 
									for (var a = 0; a < PoolSize; a++)
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -45,6 +45,7 @@ namespace FreeSql.SqlServer {
 | 
				
			|||||||
		public string Name { get; set; } = "SqlServer SqlConnection 对象池";
 | 
							public string Name { get; set; } = "SqlServer SqlConnection 对象池";
 | 
				
			||||||
		public int PoolSize { get; set; } = 100;
 | 
							public int PoolSize { get; set; } = 100;
 | 
				
			||||||
		public TimeSpan SyncGetTimeout { get; set; } = TimeSpan.FromSeconds(10);
 | 
							public TimeSpan SyncGetTimeout { get; set; } = TimeSpan.FromSeconds(10);
 | 
				
			||||||
 | 
							public TimeSpan IdleTimeout { get; set; } = TimeSpan.Zero;
 | 
				
			||||||
		public int AsyncGetCapacity { get; set; } = 10000;
 | 
							public int AsyncGetCapacity { get; set; } = 10000;
 | 
				
			||||||
		public bool IsThrowGetTimeoutException { get; set; } = true;
 | 
							public bool IsThrowGetTimeoutException { get; set; } = true;
 | 
				
			||||||
		public int CheckAvailableInterval { get; set; } = 5;
 | 
							public int CheckAvailableInterval { get; set; } = 5;
 | 
				
			||||||
@@ -54,15 +55,23 @@ namespace FreeSql.SqlServer {
 | 
				
			|||||||
		public string ConnectionString {
 | 
							public string ConnectionString {
 | 
				
			||||||
			get => _connectionString;
 | 
								get => _connectionString;
 | 
				
			||||||
			set {
 | 
								set {
 | 
				
			||||||
				var connStr = value ?? "";
 | 
									_connectionString = value ?? "";
 | 
				
			||||||
				var poolsizePatern = @"Max\s*pool\s*size\s*=\s*(\d+)";
 | 
					
 | 
				
			||||||
				Match m = Regex.Match(connStr, poolsizePatern, RegexOptions.IgnoreCase);
 | 
									var pattern = @"Max\s*pool\s*size\s*=\s*(\d+)";
 | 
				
			||||||
 | 
									Match m = Regex.Match(_connectionString, pattern, RegexOptions.IgnoreCase);
 | 
				
			||||||
				if (m.Success == false || int.TryParse(m.Groups[1].Value, out var poolsize) == false || poolsize <= 0) poolsize = 100;
 | 
									if (m.Success == false || int.TryParse(m.Groups[1].Value, out var poolsize) == false || poolsize <= 0) poolsize = 100;
 | 
				
			||||||
				var connStrIncr = dicConnStrIncr.AddOrUpdate(connStr, 1, (oldkey, oldval) => oldval + 1);
 | 
									var connStrIncr = dicConnStrIncr.AddOrUpdate(_connectionString, 1, (oldkey, oldval) => oldval + 1);
 | 
				
			||||||
				PoolSize = poolsize + connStrIncr;
 | 
									PoolSize = poolsize + connStrIncr;
 | 
				
			||||||
				_connectionString = m.Success ?
 | 
									_connectionString = m.Success ?
 | 
				
			||||||
					Regex.Replace(connStr, poolsizePatern, $"Max pool size={PoolSize}", RegexOptions.IgnoreCase) :
 | 
										Regex.Replace(_connectionString, pattern, $"Max pool size={PoolSize}", RegexOptions.IgnoreCase) :
 | 
				
			||||||
					$"{connStr};Max pool size={PoolSize}";
 | 
										$"{_connectionString};Max pool size={PoolSize}";
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
									pattern = @"Connection\s*LifeTime\s*=\s*(\d+)";
 | 
				
			||||||
 | 
									m = Regex.Match(_connectionString, pattern, RegexOptions.IgnoreCase);
 | 
				
			||||||
 | 
									if (m.Success) {
 | 
				
			||||||
 | 
										IdleTimeout = TimeSpan.FromSeconds(int.Parse(m.Groups[1].Value));
 | 
				
			||||||
 | 
										_connectionString = Regex.Replace(_connectionString, pattern, "", RegexOptions.IgnoreCase);
 | 
				
			||||||
 | 
									}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
				var initConns = new List<Object<DbConnection>>();
 | 
									var initConns = new List<Object<DbConnection>>();
 | 
				
			||||||
				for (var a = 0; a < PoolSize; a++)
 | 
									for (var a = 0; a < PoolSize; a++)
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -45,6 +45,7 @@ namespace FreeSql.Sqlite {
 | 
				
			|||||||
		public string Name { get; set; } = "Sqlite SQLiteConnection 对象池";
 | 
							public string Name { get; set; } = "Sqlite SQLiteConnection 对象池";
 | 
				
			||||||
		public int PoolSize { get; set; } = 100;
 | 
							public int PoolSize { get; set; } = 100;
 | 
				
			||||||
		public TimeSpan SyncGetTimeout { get; set; } = TimeSpan.FromSeconds(10);
 | 
							public TimeSpan SyncGetTimeout { get; set; } = TimeSpan.FromSeconds(10);
 | 
				
			||||||
 | 
							public TimeSpan IdleTimeout { get; set; } = TimeSpan.Zero;
 | 
				
			||||||
		public int AsyncGetCapacity { get; set; } = 10000;
 | 
							public int AsyncGetCapacity { get; set; } = 10000;
 | 
				
			||||||
		public bool IsThrowGetTimeoutException { get; set; } = true;
 | 
							public bool IsThrowGetTimeoutException { get; set; } = true;
 | 
				
			||||||
		public int CheckAvailableInterval { get; set; } = 5;
 | 
							public int CheckAvailableInterval { get; set; } = 5;
 | 
				
			||||||
@@ -55,15 +56,23 @@ namespace FreeSql.Sqlite {
 | 
				
			|||||||
		public string ConnectionString {
 | 
							public string ConnectionString {
 | 
				
			||||||
			get => _connectionString;
 | 
								get => _connectionString;
 | 
				
			||||||
			set {
 | 
								set {
 | 
				
			||||||
				var connStr = value ?? "";
 | 
									_connectionString = value ?? "";
 | 
				
			||||||
				var poolsizePatern = @"Max\s*pool\s*size\s*=\s*(\d+)";
 | 
					
 | 
				
			||||||
				Match m = Regex.Match(connStr, poolsizePatern, RegexOptions.IgnoreCase);
 | 
									var pattern = @"Max\s*pool\s*size\s*=\s*(\d+)";
 | 
				
			||||||
 | 
									Match m = Regex.Match(_connectionString, pattern, RegexOptions.IgnoreCase);
 | 
				
			||||||
				if (m.Success == false || int.TryParse(m.Groups[1].Value, out var poolsize) == false || poolsize <= 0) poolsize = 100;
 | 
									if (m.Success == false || int.TryParse(m.Groups[1].Value, out var poolsize) == false || poolsize <= 0) poolsize = 100;
 | 
				
			||||||
				var connStrIncr = dicConnStrIncr.AddOrUpdate(connStr, 1, (oldkey, oldval) => oldval + 1);
 | 
									var connStrIncr = dicConnStrIncr.AddOrUpdate(_connectionString, 1, (oldkey, oldval) => oldval + 1);
 | 
				
			||||||
				PoolSize = poolsize + connStrIncr;
 | 
									PoolSize = poolsize + connStrIncr;
 | 
				
			||||||
				_connectionString = m.Success ?
 | 
									_connectionString = m.Success ?
 | 
				
			||||||
					Regex.Replace(connStr, poolsizePatern, $"Max pool size={PoolSize}", RegexOptions.IgnoreCase) :
 | 
										Regex.Replace(_connectionString, pattern, $"Max pool size={PoolSize}", RegexOptions.IgnoreCase) :
 | 
				
			||||||
					$"{connStr};Max pool size={PoolSize}";
 | 
										$"{_connectionString};Max pool size={PoolSize}";
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
									pattern = @"Connection\s*LifeTime\s*=\s*(\d+)";
 | 
				
			||||||
 | 
									m = Regex.Match(_connectionString, pattern, RegexOptions.IgnoreCase);
 | 
				
			||||||
 | 
									if (m.Success) {
 | 
				
			||||||
 | 
										IdleTimeout = TimeSpan.FromSeconds(int.Parse(m.Groups[1].Value));
 | 
				
			||||||
 | 
										_connectionString = Regex.Replace(_connectionString, pattern, "", RegexOptions.IgnoreCase);
 | 
				
			||||||
 | 
									}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
				var att = Regex.Split(_connectionString, @"Attachs\s*=\s*", RegexOptions.IgnoreCase);
 | 
									var att = Regex.Split(_connectionString, @"Attachs\s*=\s*", RegexOptions.IgnoreCase);
 | 
				
			||||||
				if (att.Length == 2) {
 | 
									if (att.Length == 2) {
 | 
				
			||||||
 
 | 
				
			|||||||
		Reference in New Issue
	
	Block a user