mirror of
				https://github.com/nsnail/FreeSql.git
				synced 2025-11-04 01:05:27 +08:00 
			
		
		
		
	## v0.3.16
- 修复 IInsert/IUpdate.NoneParameter() 设成了反作用的 bug; - 修复 IDbFirst.GetTablesByDatabase() 默认数据库 bool 判断 bug; - 增加 FreeSql.Repository 之 IUnitOfWork 实现,[查看参数资料](https://github.com/2881099/FreeSql/wiki/%e5%b7%a5%e4%bd%9c%e5%8d%95%e5%85%83); - 增加 FreeSql.Repository 继承实现的仓储注入; ```csharp builder.RegisterFreeRepository( filter => filter.Apply<Song>("test", a => a.Title == DateTime.Now.ToString() + Thread.CurrentThread.ManagedThreadId), this.GetType().Assembly ); ```
This commit is contained in:
		@@ -9,60 +9,18 @@ using System.Linq;
 | 
			
		||||
 | 
			
		||||
public static class FreeSqlRepositoryAutofacExtenssions {
 | 
			
		||||
 | 
			
		||||
	public static void RegisterFreeRepository(this ContainerBuilder builder, Action<GlobalDataFilter> globalDataFilter) => RegisterFreeRepositoryPrivate(builder, globalDataFilter);
 | 
			
		||||
	/// <summary>
 | 
			
		||||
	/// 注册 FreeSql.Repository 包括 泛型、继承实现的仓储
 | 
			
		||||
	/// </summary>
 | 
			
		||||
	/// <param name="builder"></param>
 | 
			
		||||
	/// <param name="globalDataFilter">全局过滤设置</param>
 | 
			
		||||
	/// <param name="assemblies">继承实现的仓储,所在的程序集</param>
 | 
			
		||||
	public static void RegisterFreeRepository(this ContainerBuilder builder, Action<FluentDataFilter> globalDataFilter = null, params Assembly[] assemblies) => 
 | 
			
		||||
		RegisterFreeRepositoryPrivate(builder, globalDataFilter, assemblies);
 | 
			
		||||
 | 
			
		||||
	static ConcurrentDictionary<Type, Delegate> _dicRegisterFreeRepositoryPrivateSetFilterFunc = new ConcurrentDictionary<Type, Delegate>();
 | 
			
		||||
	static ConcurrentDictionary<Type, ConcurrentDictionary<string, bool>> _dicRegisterFreeRepositoryPrivateConvertFilterNotExists = new ConcurrentDictionary<Type, ConcurrentDictionary<string, bool>>();
 | 
			
		||||
	static void RegisterFreeRepositoryPrivate(ContainerBuilder builder, Action<GlobalDataFilter> globalDataFilter) {
 | 
			
		||||
	static void RegisterFreeRepositoryPrivate(ContainerBuilder builder, Action<FluentDataFilter> globalDataFilter, params Assembly[] assemblies) {
 | 
			
		||||
 | 
			
		||||
		Action<object> funcSetDataFilter = instance => {
 | 
			
		||||
			if (globalDataFilter == null) return;
 | 
			
		||||
			var globalFilter = new GlobalDataFilter();
 | 
			
		||||
			globalDataFilter(globalFilter);
 | 
			
		||||
 | 
			
		||||
			var type = instance.GetType();
 | 
			
		||||
			var entityType = type.GenericTypeArguments[0];
 | 
			
		||||
 | 
			
		||||
			var notExists = _dicRegisterFreeRepositoryPrivateConvertFilterNotExists.GetOrAdd(type, t => new ConcurrentDictionary<string, bool>());
 | 
			
		||||
			var newFilter = new Dictionary<string, LambdaExpression>();
 | 
			
		||||
			foreach (var gf in globalFilter._filters) {
 | 
			
		||||
				if (notExists.ContainsKey(gf.name)) continue;
 | 
			
		||||
 | 
			
		||||
				LambdaExpression newExp = null;
 | 
			
		||||
				var filterParameter1 = Expression.Parameter(entityType, gf.exp.Parameters[0].Name);
 | 
			
		||||
				try {
 | 
			
		||||
					newExp = Expression.Lambda(
 | 
			
		||||
						typeof(Func<,>).MakeGenericType(entityType, typeof(bool)),
 | 
			
		||||
						new ReplaceVisitor().Modify(gf.exp.Body, filterParameter1),
 | 
			
		||||
						filterParameter1
 | 
			
		||||
					);
 | 
			
		||||
				} catch {
 | 
			
		||||
					notExists.TryAdd(gf.name, true); //防止第二次错误
 | 
			
		||||
					continue;
 | 
			
		||||
				}
 | 
			
		||||
				newFilter.Add(gf.name, gf.exp);
 | 
			
		||||
			}
 | 
			
		||||
			if (newFilter.Any() == false) return;
 | 
			
		||||
 | 
			
		||||
			var del = _dicRegisterFreeRepositoryPrivateSetFilterFunc.GetOrAdd(type, t => {
 | 
			
		||||
				var reposParameter = Expression.Parameter(type);
 | 
			
		||||
				var nameParameter = Expression.Parameter(typeof(string));
 | 
			
		||||
				var expressionParameter = Expression.Parameter(
 | 
			
		||||
					typeof(Expression<>).MakeGenericType(typeof(Func<,>).MakeGenericType(entityType, typeof(bool)))
 | 
			
		||||
				);
 | 
			
		||||
				return Expression.Lambda(
 | 
			
		||||
					Expression.Block(
 | 
			
		||||
						Expression.Call(reposParameter, type.GetMethod("ApplyDataFilter", BindingFlags.Instance | BindingFlags.NonPublic), nameParameter, expressionParameter)
 | 
			
		||||
					),
 | 
			
		||||
					new[] {
 | 
			
		||||
						reposParameter, nameParameter, expressionParameter
 | 
			
		||||
					}
 | 
			
		||||
				).Compile();
 | 
			
		||||
			});
 | 
			
		||||
			foreach (var nf in newFilter) {
 | 
			
		||||
				del.DynamicInvoke(instance, nf.Key, nf.Value);
 | 
			
		||||
			}
 | 
			
		||||
		};
 | 
			
		||||
		Utils._globalDataFilter = globalDataFilter;
 | 
			
		||||
 | 
			
		||||
		builder.RegisterGeneric(typeof(GuidRepository<>)).As(
 | 
			
		||||
			typeof(GuidRepository<>),
 | 
			
		||||
@@ -70,31 +28,21 @@ public static class FreeSqlRepositoryAutofacExtenssions {
 | 
			
		||||
			typeof(IBasicRepository<>),
 | 
			
		||||
			typeof(IReadOnlyRepository<>)
 | 
			
		||||
		).OnActivating(a => {
 | 
			
		||||
			funcSetDataFilter(a.Instance);
 | 
			
		||||
			//Utils.SetRepositoryDataFilter(a.Instance);
 | 
			
		||||
		}).InstancePerDependency();
 | 
			
		||||
 | 
			
		||||
		
 | 
			
		||||
		builder.RegisterGeneric(typeof(DefaultRepository<,>)).As(
 | 
			
		||||
			typeof(DefaultRepository<,>),
 | 
			
		||||
			typeof(BaseRepository<,>),
 | 
			
		||||
			typeof(IBasicRepository<,>),
 | 
			
		||||
			typeof(IReadOnlyRepository<,>)
 | 
			
		||||
		).OnActivating(a => {
 | 
			
		||||
			funcSetDataFilter(a.Instance);
 | 
			
		||||
			//Utils.SetRepositoryDataFilter(a.Instance);
 | 
			
		||||
		}).InstancePerDependency();
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	class ReplaceVisitor : ExpressionVisitor {
 | 
			
		||||
		private ParameterExpression parameter;
 | 
			
		||||
		builder.RegisterAssemblyTypes(assemblies).Where(a => {
 | 
			
		||||
			return typeof(IRepository).IsAssignableFrom(a);
 | 
			
		||||
		}).InstancePerDependency();
 | 
			
		||||
 | 
			
		||||
		public Expression Modify(Expression expression, ParameterExpression parameter) {
 | 
			
		||||
			this.parameter = parameter;
 | 
			
		||||
			return Visit(expression);
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		protected override Expression VisitMember(MemberExpression node) {
 | 
			
		||||
			if (node.Expression?.NodeType == ExpressionType.Parameter)
 | 
			
		||||
				return Expression.Property(parameter, node.Member.Name);
 | 
			
		||||
			return base.VisitMember(node);
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
}
 | 
			
		||||
 
 | 
			
		||||
@@ -18,16 +18,8 @@ public static class FreeSqlRepositoryIFreeSqlExtenssions {
 | 
			
		||||
	/// <param name="filter">数据过滤 + 验证</param>
 | 
			
		||||
	/// <returns></returns>
 | 
			
		||||
	public static DefaultRepository<TEntity, TKey> GetRepository<TEntity, TKey>(this IFreeSql that, Expression<Func<TEntity, bool>> filter = null) where TEntity : class {
 | 
			
		||||
 | 
			
		||||
		if (filter != null) return new DefaultRepository<TEntity, TKey>(that, filter);
 | 
			
		||||
		return dicGetRepository
 | 
			
		||||
			.GetOrAdd(typeof(TEntity), key1 => new ConcurrentDictionary<Type, IRepository>())
 | 
			
		||||
			.GetOrAdd(typeof(TKey), key2 => new DefaultRepository<TEntity, TKey>(that, null)) as DefaultRepository<TEntity, TKey>;
 | 
			
		||||
		return new DefaultRepository<TEntity, TKey>(that, filter);
 | 
			
		||||
	}
 | 
			
		||||
	static ConcurrentDictionary<Type,
 | 
			
		||||
		ConcurrentDictionary<Type,
 | 
			
		||||
			IRepository>
 | 
			
		||||
		> dicGetRepository = new ConcurrentDictionary<Type, ConcurrentDictionary<Type, IRepository>>();
 | 
			
		||||
 | 
			
		||||
	/// <summary>
 | 
			
		||||
	/// 返回仓库类,适用 Insert 方法无须返回插入的数据
 | 
			
		||||
@@ -38,12 +30,8 @@ public static class FreeSqlRepositoryIFreeSqlExtenssions {
 | 
			
		||||
	/// <param name="asTable">分表规则,参数:旧表名;返回:新表名 https://github.com/2881099/FreeSql/wiki/Repository</param>
 | 
			
		||||
	/// <returns></returns>
 | 
			
		||||
	public static GuidRepository<TEntity> GetGuidRepository<TEntity>(this IFreeSql that, Expression<Func<TEntity, bool>> filter = null, Func<string, string> asTable = null) where TEntity : class {
 | 
			
		||||
 | 
			
		||||
		if (filter != null || asTable != null) return new GuidRepository<TEntity>(that, filter, asTable);
 | 
			
		||||
		return dicGetGuidRepository
 | 
			
		||||
			.GetOrAdd(typeof(TEntity), key1 => new GuidRepository<TEntity>(that, null, null)) as GuidRepository<TEntity>;
 | 
			
		||||
		return new GuidRepository<TEntity>(that, filter, asTable);
 | 
			
		||||
	}
 | 
			
		||||
	static ConcurrentDictionary<Type, IRepository> dicGetGuidRepository = new ConcurrentDictionary<Type, IRepository>();
 | 
			
		||||
 | 
			
		||||
	/// <summary>
 | 
			
		||||
	/// 合并两个仓储的设置(过滤+分表),以便查询
 | 
			
		||||
@@ -58,4 +46,13 @@ public static class FreeSqlRepositoryIFreeSqlExtenssions {
 | 
			
		||||
		foreach (var filter in filters) that.Where<T2>(filter.Value.Expression);
 | 
			
		||||
		return that.AsTable(repos.AsTableSelectInternal);
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	/// <summary>
 | 
			
		||||
	/// 创建一个新的工作单元,务必使用 using 包含使用
 | 
			
		||||
	/// </summary>
 | 
			
		||||
	/// <param name="that"></param>
 | 
			
		||||
	/// <returns></returns>
 | 
			
		||||
	public static IUnitOfWork CreateUnitOfWork(this IFreeSql that) {
 | 
			
		||||
		return new UnitOfWork(that);
 | 
			
		||||
	}
 | 
			
		||||
}
 | 
			
		||||
		Reference in New Issue
	
	Block a user