mirror of
				https://github.com/nsnail/FreeSql.git
				synced 2025-11-04 09:15:27 +08:00 
			
		
		
		
	rename DbContext Internal Method
This commit is contained in:
		@@ -1,8 +1,9 @@
 | 
			
		||||
using System;
 | 
			
		||||
using System.Collections.Concurrent;
 | 
			
		||||
using System.Collections.Generic;
 | 
			
		||||
using System.Linq;
 | 
			
		||||
using System.Reflection;
 | 
			
		||||
using System.Linq.Expressions;
 | 
			
		||||
using System.Reflection;
 | 
			
		||||
using System.Threading.Tasks;
 | 
			
		||||
 | 
			
		||||
#if net40
 | 
			
		||||
@@ -13,59 +14,58 @@ namespace FreeSql
 | 
			
		||||
    {
 | 
			
		||||
        async public virtual Task<int> SaveChangesAsync()
 | 
			
		||||
        {
 | 
			
		||||
            await ExecCommandAsync();
 | 
			
		||||
            await FlushCommandAsync();
 | 
			
		||||
            return SaveChangesSuccess();
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        static Dictionary<Type, Dictionary<string, Func<object, object[], Task<int>>>> _dicExecCommandDbContextBatchAsync = new Dictionary<Type, Dictionary<string, Func<object, object[], Task<int>>>>();
 | 
			
		||||
        async internal Task ExecCommandAsync()
 | 
			
		||||
        static ConcurrentDictionary<Type, ConcurrentDictionary<string, Func<object, object[], Task<int>>>> _dicFlushCommandDbSetBatchAsync = new ConcurrentDictionary<Type, ConcurrentDictionary<string, Func<object, object[], Task<int>>>>();
 | 
			
		||||
        async internal Task FlushCommandAsync()
 | 
			
		||||
        {
 | 
			
		||||
            if (isExecCommanding) return;
 | 
			
		||||
            if (_actions.Any() == false) return;
 | 
			
		||||
            isExecCommanding = true;
 | 
			
		||||
            if (isFlushCommanding) return;
 | 
			
		||||
            if (_prevCommands.Any() == false) return;
 | 
			
		||||
            isFlushCommanding = true;
 | 
			
		||||
 | 
			
		||||
            ExecCommandInfo oldinfo = null;
 | 
			
		||||
            PrevCommandInfo oldinfo = null;
 | 
			
		||||
            var states = new List<object>();
 | 
			
		||||
 | 
			
		||||
            Func<string, Task<int>> dbContextBatch = methodName =>
 | 
			
		||||
            Task<int> dbsetBatch(string method)
 | 
			
		||||
            {
 | 
			
		||||
                if (_dicExecCommandDbContextBatchAsync.TryGetValue(oldinfo.stateType, out var trydic) == false)
 | 
			
		||||
                    trydic = new Dictionary<string, Func<object, object[], Task<int>>>();
 | 
			
		||||
                if (trydic.TryGetValue(methodName, out var tryfunc) == false)
 | 
			
		||||
                {
 | 
			
		||||
                    var arrType = oldinfo.stateType.MakeArrayType();
 | 
			
		||||
                    var dbsetType = oldinfo.dbSet.GetType().BaseType;
 | 
			
		||||
                    var dbsetTypeMethod = dbsetType.GetMethod(methodName, BindingFlags.NonPublic | BindingFlags.Instance, null, new[] { arrType }, null);
 | 
			
		||||
                var tryfunc = _dicFlushCommandDbSetBatchAsync
 | 
			
		||||
                    .GetOrAdd(oldinfo.stateType, stateType => new ConcurrentDictionary<string, Func<object, object[], Task<int>>>())
 | 
			
		||||
                    .GetOrAdd(method, methodName =>
 | 
			
		||||
                    {
 | 
			
		||||
                        var arrType = oldinfo.stateType.MakeArrayType();
 | 
			
		||||
                        var dbsetType = oldinfo.dbSet.GetType().BaseType;
 | 
			
		||||
                        var dbsetTypeMethod = dbsetType.GetMethod(methodName, BindingFlags.NonPublic | BindingFlags.Instance, null, new[] { arrType }, null);
 | 
			
		||||
 | 
			
		||||
                    var returnTarget = Expression.Label(typeof(Task<int>));
 | 
			
		||||
                    var parm1DbSet = Expression.Parameter(typeof(object));
 | 
			
		||||
                    var parm2Vals = Expression.Parameter(typeof(object[]));
 | 
			
		||||
                    var var1Vals = Expression.Variable(arrType);
 | 
			
		||||
                    tryfunc = Expression.Lambda<Func<object, object[], Task<int>>>(Expression.Block(
 | 
			
		||||
                        new[] { var1Vals },
 | 
			
		||||
                        Expression.Assign(var1Vals, Expression.Convert(global::FreeSql.Internal.Utils.GetDataReaderValueBlockExpression(arrType, parm2Vals), arrType)),
 | 
			
		||||
                        Expression.Return(returnTarget, Expression.Call(Expression.Convert(parm1DbSet, dbsetType), dbsetTypeMethod, var1Vals)),
 | 
			
		||||
                        Expression.Label(returnTarget, Expression.Default(typeof(Task<int>)))
 | 
			
		||||
                    ), new[] { parm1DbSet, parm2Vals }).Compile();
 | 
			
		||||
                    trydic.Add(methodName, tryfunc);
 | 
			
		||||
                }
 | 
			
		||||
                        var returnTarget = Expression.Label(typeof(Task<int>));
 | 
			
		||||
                        var parm1DbSet = Expression.Parameter(typeof(object));
 | 
			
		||||
                        var parm2Vals = Expression.Parameter(typeof(object[]));
 | 
			
		||||
                        var var1Vals = Expression.Variable(arrType);
 | 
			
		||||
                        return Expression.Lambda<Func<object, object[], Task<int>>>(Expression.Block(
 | 
			
		||||
                            new[] { var1Vals },
 | 
			
		||||
                            Expression.Assign(var1Vals, Expression.Convert(global::FreeSql.Internal.Utils.GetDataReaderValueBlockExpression(arrType, parm2Vals), arrType)),
 | 
			
		||||
                            Expression.Return(returnTarget, Expression.Call(Expression.Convert(parm1DbSet, dbsetType), dbsetTypeMethod, var1Vals)),
 | 
			
		||||
                            Expression.Label(returnTarget, Expression.Default(typeof(Task<int>)))
 | 
			
		||||
                        ), new[] { parm1DbSet, parm2Vals }).Compile();
 | 
			
		||||
                    });
 | 
			
		||||
                return tryfunc(oldinfo.dbSet, states.ToArray());
 | 
			
		||||
            };
 | 
			
		||||
            Func<Task> funcDelete = async () =>
 | 
			
		||||
            }
 | 
			
		||||
            async Task funcDelete()
 | 
			
		||||
            {
 | 
			
		||||
                _affrows += await dbContextBatch("DbContextBatchRemoveAsync");
 | 
			
		||||
                _affrows += await dbsetBatch("DbContextBatchRemoveAsync");
 | 
			
		||||
                states.Clear();
 | 
			
		||||
            }
 | 
			
		||||
            async Task funcInsert()
 | 
			
		||||
            {
 | 
			
		||||
                _affrows += await dbsetBatch("DbContextBatchAddAsync");
 | 
			
		||||
                states.Clear();
 | 
			
		||||
            };
 | 
			
		||||
            Func<Task> funcInsert = async () =>
 | 
			
		||||
            {
 | 
			
		||||
                _affrows += await dbContextBatch("DbContextBatchAddAsync");
 | 
			
		||||
                states.Clear();
 | 
			
		||||
            };
 | 
			
		||||
            Func<bool, Task> funcUpdate = async (isLiveUpdate) =>
 | 
			
		||||
            async Task funcUpdate(bool isLiveUpdate)
 | 
			
		||||
            {
 | 
			
		||||
                var affrows = 0;
 | 
			
		||||
                if (isLiveUpdate) affrows = await dbContextBatch("DbContextBatchUpdateNowAsync");
 | 
			
		||||
                else affrows = await dbContextBatch("DbContextBatchUpdateAsync");
 | 
			
		||||
                if (isLiveUpdate) affrows = await dbsetBatch("DbContextBatchUpdateNowAsync");
 | 
			
		||||
                else affrows = await dbsetBatch("DbContextBatchUpdateAsync");
 | 
			
		||||
                if (affrows == -999)
 | 
			
		||||
                { //最后一个元素已被删除
 | 
			
		||||
                    states.RemoveAt(states.Count - 1);
 | 
			
		||||
@@ -87,13 +87,13 @@ namespace FreeSql
 | 
			
		||||
                }
 | 
			
		||||
            };
 | 
			
		||||
 | 
			
		||||
            while (_actions.Any() || states.Any())
 | 
			
		||||
            while (_prevCommands.Any() || states.Any())
 | 
			
		||||
            {
 | 
			
		||||
                var info = _actions.Any() ? _actions.Dequeue() : null;
 | 
			
		||||
                var info = _prevCommands.Any() ? _prevCommands.Dequeue() : null;
 | 
			
		||||
                if (oldinfo == null) oldinfo = info;
 | 
			
		||||
                var isLiveUpdate = false;
 | 
			
		||||
 | 
			
		||||
                if (_actions.Any() == false && states.Any() ||
 | 
			
		||||
                if (_prevCommands.Any() == false && states.Any() ||
 | 
			
		||||
                    info != null && oldinfo.changeType != info.changeType ||
 | 
			
		||||
                    info != null && oldinfo.stateType != info.stateType ||
 | 
			
		||||
                    info != null && oldinfo.entityType != info.entityType)
 | 
			
		||||
@@ -130,7 +130,7 @@ namespace FreeSql
 | 
			
		||||
                    oldinfo = info;
 | 
			
		||||
                }
 | 
			
		||||
            }
 | 
			
		||||
            isExecCommanding = false;
 | 
			
		||||
            isFlushCommanding = false;
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 
 | 
			
		||||
		Reference in New Issue
	
	Block a user