mirror of
				https://github.com/nsnail/FreeSql.git
				synced 2025-11-04 17:20:49 +08:00 
			
		
		
		
	- 增加 ISelect.WhereCascade 实现多表查询时,向每个表中附加条件;
- 增加 Examples 项目 base_entity,利用 BaseEntity 实现简洁的数据库操作;
This commit is contained in:
		@@ -2,7 +2,7 @@
 | 
			
		||||
 | 
			
		||||
	<PropertyGroup>
 | 
			
		||||
		<TargetFrameworks>netstandard2.0;net45</TargetFrameworks>
 | 
			
		||||
		<Version>0.7.12</Version>
 | 
			
		||||
		<Version>0.7.13</Version>
 | 
			
		||||
		<GeneratePackageOnBuild>true</GeneratePackageOnBuild>
 | 
			
		||||
		<Authors>YeXiangQin</Authors>
 | 
			
		||||
		<Description>FreeSql is the most convenient ORM in dotnet. It supports Mysql, Postgresql, SqlServer, Oracle and Sqlite.</Description>
 | 
			
		||||
 
 | 
			
		||||
@@ -1259,6 +1259,21 @@
 | 
			
		||||
            <param name="dywhere">主键值、主键值集合、实体、实体集合、匿名对象、匿名对象集合</param>
 | 
			
		||||
            <returns></returns>
 | 
			
		||||
        </member>
 | 
			
		||||
        <member name="M:FreeSql.ISelect`1.WhereCascade(System.Linq.Expressions.Expression{System.Func{`0,System.Boolean}})">
 | 
			
		||||
            <summary>
 | 
			
		||||
            多表查询时,该方法标记后,表达式条件将对所有表进行附加
 | 
			
		||||
            <para></para>
 | 
			
		||||
            例如:软删除、租户,每个表都给条件,挺麻烦的
 | 
			
		||||
            <para></para>
 | 
			
		||||
            fsql.Select<T1>().LeftJoin<T2>(...).Where<T2>((t1, t2 => t1.IsDeleted == false && t2.IsDeleted == false)
 | 
			
		||||
            <para></para>
 | 
			
		||||
            修改:fsql.Select<T1>().LeftJoin<T2>(...).WhereCascade(t1 => t1.IsDeleted == false)
 | 
			
		||||
            <para></para>
 | 
			
		||||
            当其中的实体可附加表达式才会进行,表越多时收益越大
 | 
			
		||||
            </summary>
 | 
			
		||||
            <param name="exp"></param>
 | 
			
		||||
            <returns></returns>
 | 
			
		||||
        </member>
 | 
			
		||||
        <member name="M:FreeSql.ISelect`1.GroupBy``1(System.Linq.Expressions.Expression{System.Func{`0,``0}})">
 | 
			
		||||
            <summary>
 | 
			
		||||
            按选择的列分组,GroupBy(a => a.Name) | GroupBy(a => new{a.Name,a.Time})
 | 
			
		||||
 
 | 
			
		||||
@@ -3,6 +3,8 @@ using System;
 | 
			
		||||
using System.Collections.Concurrent;
 | 
			
		||||
using System.Data.Common;
 | 
			
		||||
using System.Diagnostics;
 | 
			
		||||
using System.Security.Cryptography;
 | 
			
		||||
using System.Text;
 | 
			
		||||
using System.Threading;
 | 
			
		||||
using System.Threading.Tasks;
 | 
			
		||||
 | 
			
		||||
@@ -33,4 +35,16 @@ public static class FreeUtil
 | 
			
		||||
        var guid = $"{uninxtime.ToString("x8").PadLeft(8, '0')}{__staticMachine.ToString("x8").PadLeft(8, '0').Substring(2, 6)}{__staticPid.ToString("x8").PadLeft(8, '0').Substring(6, 2)}{increment.ToString("x8").PadLeft(8, '0')}{rand.ToString("x8").PadLeft(8, '0')}";
 | 
			
		||||
        return Guid.Parse(guid);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    public static string Sha1(string str)
 | 
			
		||||
    {
 | 
			
		||||
        var buffer = Encoding.UTF8.GetBytes(str);
 | 
			
		||||
        var data = SHA1.Create().ComputeHash(buffer);
 | 
			
		||||
 | 
			
		||||
        var sub = new StringBuilder();
 | 
			
		||||
        foreach (var t in data)
 | 
			
		||||
            sub.Append(t.ToString("X2"));
 | 
			
		||||
 | 
			
		||||
        return sub.ToString();
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
@@ -275,6 +275,21 @@ namespace FreeSql
 | 
			
		||||
        /// <returns></returns>
 | 
			
		||||
        ISelect<T1> WhereDynamic(object dywhere);
 | 
			
		||||
 | 
			
		||||
        /// <summary>
 | 
			
		||||
        /// 多表查询时,该方法标记后,表达式条件将对所有表进行附加
 | 
			
		||||
        /// <para></para>
 | 
			
		||||
        /// 例如:软删除、租户,每个表都给条件,挺麻烦的
 | 
			
		||||
        /// <para></para>
 | 
			
		||||
        /// fsql.Select<T1>().LeftJoin<T2>(...).Where<T2>((t1, t2 => t1.IsDeleted == false && t2.IsDeleted == false)
 | 
			
		||||
        /// <para></para>
 | 
			
		||||
        /// 修改:fsql.Select<T1>().LeftJoin<T2>(...).WhereCascade(t1 => t1.IsDeleted == false)
 | 
			
		||||
        /// <para></para>
 | 
			
		||||
        /// 当其中的实体可附加表达式才会进行,表越多时收益越大
 | 
			
		||||
        /// </summary>
 | 
			
		||||
        /// <param name="exp"></param>
 | 
			
		||||
        /// <returns></returns>
 | 
			
		||||
        ISelect<T1> WhereCascade(Expression<Func<T1, bool>> exp);
 | 
			
		||||
 | 
			
		||||
        /// <summary>
 | 
			
		||||
        /// 按选择的列分组,GroupBy(a => a.Name) | GroupBy(a => new{a.Name,a.Time})
 | 
			
		||||
        /// </summary>
 | 
			
		||||
 
 | 
			
		||||
@@ -24,20 +24,20 @@ namespace FreeSql.Internal
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        static ConcurrentDictionary<Type, PropertyInfo[]> _dicReadAnonymousFieldDtoPropertys = new ConcurrentDictionary<Type, PropertyInfo[]>();
 | 
			
		||||
        public bool ReadAnonymousField(List<SelectTableInfo> _tables, StringBuilder field, ReadAnonymousTypeInfo parent, ref int index, Expression exp, Func<Expression[], string> getSelectGroupingMapString)
 | 
			
		||||
        public bool ReadAnonymousField(List<SelectTableInfo> _tables, StringBuilder field, ReadAnonymousTypeInfo parent, ref int index, Expression exp, Func<Expression[], string> getSelectGroupingMapString, List<LambdaExpression> whereCascadeExpression)
 | 
			
		||||
        {
 | 
			
		||||
            Func<ExpTSC> getTSC = () => new ExpTSC { _tables = _tables, getSelectGroupingMapString = getSelectGroupingMapString, tbtype = SelectTableInfoType.From, isQuoteName = true, isDisableDiyParse = false, style = ExpressionStyle.Where };
 | 
			
		||||
            Func<ExpTSC> getTSC = () => new ExpTSC { _tables = _tables, getSelectGroupingMapString = getSelectGroupingMapString, tbtype = SelectTableInfoType.From, isQuoteName = true, isDisableDiyParse = false, style = ExpressionStyle.Where, whereCascadeExpression = whereCascadeExpression };
 | 
			
		||||
            switch (exp.NodeType)
 | 
			
		||||
            {
 | 
			
		||||
                case ExpressionType.Quote: return ReadAnonymousField(_tables, field, parent, ref index, (exp as UnaryExpression)?.Operand, getSelectGroupingMapString);
 | 
			
		||||
                case ExpressionType.Lambda: return ReadAnonymousField(_tables, field, parent, ref index, (exp as LambdaExpression)?.Body, getSelectGroupingMapString);
 | 
			
		||||
                case ExpressionType.Quote: return ReadAnonymousField(_tables, field, parent, ref index, (exp as UnaryExpression)?.Operand, getSelectGroupingMapString, whereCascadeExpression);
 | 
			
		||||
                case ExpressionType.Lambda: return ReadAnonymousField(_tables, field, parent, ref index, (exp as LambdaExpression)?.Body, getSelectGroupingMapString, whereCascadeExpression);
 | 
			
		||||
                case ExpressionType.Negate:
 | 
			
		||||
                case ExpressionType.NegateChecked:
 | 
			
		||||
                    parent.DbField = $"-({ExpressionLambdaToSql(exp, getTSC())})";
 | 
			
		||||
                    field.Append(", ").Append(parent.DbField);
 | 
			
		||||
                    if (index >= 0) field.Append(" as").Append(++index);
 | 
			
		||||
                    return false;
 | 
			
		||||
                case ExpressionType.Convert: return ReadAnonymousField(_tables, field, parent, ref index, (exp as UnaryExpression)?.Operand, getSelectGroupingMapString);
 | 
			
		||||
                case ExpressionType.Convert: return ReadAnonymousField(_tables, field, parent, ref index, (exp as UnaryExpression)?.Operand, getSelectGroupingMapString, whereCascadeExpression);
 | 
			
		||||
                case ExpressionType.Constant:
 | 
			
		||||
                    var constExp = exp as ConstantExpression;
 | 
			
		||||
                    //处理自定义SQL语句,如: ToList(new { 
 | 
			
		||||
@@ -117,7 +117,7 @@ namespace FreeSql.Internal
 | 
			
		||||
                                MapType = initAssignExp.Expression.Type
 | 
			
		||||
                            };
 | 
			
		||||
                            parent.Childs.Add(child);
 | 
			
		||||
                            ReadAnonymousField(_tables, field, child, ref index, initAssignExp.Expression, getSelectGroupingMapString);
 | 
			
		||||
                            ReadAnonymousField(_tables, field, child, ref index, initAssignExp.Expression, getSelectGroupingMapString, whereCascadeExpression);
 | 
			
		||||
                        }
 | 
			
		||||
                    }
 | 
			
		||||
                    else
 | 
			
		||||
@@ -139,7 +139,7 @@ namespace FreeSql.Internal
 | 
			
		||||
                                    };
 | 
			
		||||
                                    parent.Childs.Add(child);
 | 
			
		||||
                                    if (dtTb.Parameter != null)
 | 
			
		||||
                                        ReadAnonymousField(_tables, field, child, ref index, Expression.Property(dtTb.Parameter, dtTb.Table.Properties[trydtocol.CsName]), getSelectGroupingMapString);
 | 
			
		||||
                                        ReadAnonymousField(_tables, field, child, ref index, Expression.Property(dtTb.Parameter, dtTb.Table.Properties[trydtocol.CsName]), getSelectGroupingMapString, whereCascadeExpression);
 | 
			
		||||
                                    else
 | 
			
		||||
                                    {
 | 
			
		||||
                                        child.DbField = $"{dtTb.Alias}.{_common.QuoteSqlName(trydtocol.Attribute.Name)}";
 | 
			
		||||
@@ -169,7 +169,7 @@ namespace FreeSql.Internal
 | 
			
		||||
                                MapType = newExp.Arguments[a].Type
 | 
			
		||||
                            };
 | 
			
		||||
                            parent.Childs.Add(child);
 | 
			
		||||
                            ReadAnonymousField(_tables, field, child, ref index, newExp.Arguments[a], getSelectGroupingMapString);
 | 
			
		||||
                            ReadAnonymousField(_tables, field, child, ref index, newExp.Arguments[a], getSelectGroupingMapString, whereCascadeExpression);
 | 
			
		||||
                        }
 | 
			
		||||
                    }
 | 
			
		||||
                    else
 | 
			
		||||
@@ -192,7 +192,7 @@ namespace FreeSql.Internal
 | 
			
		||||
                                    };
 | 
			
		||||
                                    parent.Childs.Add(child);
 | 
			
		||||
                                    if (dtTb.Parameter != null)
 | 
			
		||||
                                        ReadAnonymousField(_tables, field, child, ref index, Expression.Property(dtTb.Parameter, dtTb.Table.Properties[trydtocol.CsName]), getSelectGroupingMapString);
 | 
			
		||||
                                        ReadAnonymousField(_tables, field, child, ref index, Expression.Property(dtTb.Parameter, dtTb.Table.Properties[trydtocol.CsName]), getSelectGroupingMapString, whereCascadeExpression);
 | 
			
		||||
                                    else
 | 
			
		||||
                                    {
 | 
			
		||||
                                        child.DbField = $"{dtTb.Alias}.{_common.QuoteSqlName(trydtocol.Attribute.Name)}";
 | 
			
		||||
@@ -332,9 +332,9 @@ namespace FreeSql.Internal
 | 
			
		||||
            return sql;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        public string ExpressionWhereLambda(List<SelectTableInfo> _tables, Expression exp, Func<Expression[], string> getSelectGroupingMapString)
 | 
			
		||||
        public string ExpressionWhereLambda(List<SelectTableInfo> _tables, Expression exp, Func<Expression[], string> getSelectGroupingMapString, List<LambdaExpression> whereCascadeExpression)
 | 
			
		||||
        {
 | 
			
		||||
            var sql = ExpressionLambdaToSql(exp, new ExpTSC { _tables = _tables, getSelectGroupingMapString = getSelectGroupingMapString, tbtype = SelectTableInfoType.From, isQuoteName = true, isDisableDiyParse = false, style = ExpressionStyle.Where });
 | 
			
		||||
            var sql = ExpressionLambdaToSql(exp, new ExpTSC { _tables = _tables, getSelectGroupingMapString = getSelectGroupingMapString, tbtype = SelectTableInfoType.From, isQuoteName = true, isDisableDiyParse = false, style = ExpressionStyle.Where, whereCascadeExpression = whereCascadeExpression });
 | 
			
		||||
            var isBool = exp.Type.NullableTypeOrThis() == typeof(bool);
 | 
			
		||||
            if (exp.NodeType == ExpressionType.MemberAccess && isBool && sql.Contains(" IS ") == false && sql.Contains(" = ") == false)
 | 
			
		||||
                return $"{sql} = {formatSql(true, null)}";
 | 
			
		||||
@@ -343,10 +343,10 @@ namespace FreeSql.Internal
 | 
			
		||||
            return sql;
 | 
			
		||||
        }
 | 
			
		||||
        static ConcurrentDictionary<string, Regex> dicRegexAlias = new ConcurrentDictionary<string, Regex>();
 | 
			
		||||
        public void ExpressionJoinLambda(List<SelectTableInfo> _tables, SelectTableInfoType tbtype, Expression exp, Func<Expression[], string> getSelectGroupingMapString)
 | 
			
		||||
        public void ExpressionJoinLambda(List<SelectTableInfo> _tables, SelectTableInfoType tbtype, Expression exp, Func<Expression[], string> getSelectGroupingMapString, List<LambdaExpression> whereCascadeExpression)
 | 
			
		||||
        {
 | 
			
		||||
            var tbidx = _tables.Count;
 | 
			
		||||
            var sql = ExpressionLambdaToSql(exp, new ExpTSC { _tables = _tables, getSelectGroupingMapString = getSelectGroupingMapString, tbtype = tbtype, isQuoteName = true, isDisableDiyParse = false, style = ExpressionStyle.Where });
 | 
			
		||||
            var sql = ExpressionLambdaToSql(exp, new ExpTSC { _tables = _tables, getSelectGroupingMapString = getSelectGroupingMapString, tbtype = tbtype, isQuoteName = true, isDisableDiyParse = false, style = ExpressionStyle.Where, whereCascadeExpression = whereCascadeExpression });
 | 
			
		||||
            var isBool = exp.Type.NullableTypeOrThis() == typeof(bool);
 | 
			
		||||
            if (exp.NodeType == ExpressionType.MemberAccess && isBool && sql.Contains(" IS ") == false && sql.Contains(" = ") == false)
 | 
			
		||||
                sql = $"{sql} = {formatSql(true, null)}";
 | 
			
		||||
@@ -362,8 +362,8 @@ namespace FreeSql.Internal
 | 
			
		||||
            }
 | 
			
		||||
            else
 | 
			
		||||
            {
 | 
			
		||||
                var find = _tables.Where((a, c) => c > 0 && 
 | 
			
		||||
                    (a.Type == tbtype || a.Type == SelectTableInfoType.From) && 
 | 
			
		||||
                var find = _tables.Where((a, c) => c > 0 &&
 | 
			
		||||
                    (a.Type == tbtype || a.Type == SelectTableInfoType.From) &&
 | 
			
		||||
                    string.IsNullOrEmpty(a.On) &&
 | 
			
		||||
                    dicRegexAlias.GetOrAdd(a.Alias, alias => new Regex($@"\b{alias}\.", RegexOptions.Compiled)).IsMatch(sql)).LastOrDefault();
 | 
			
		||||
                if (find != null)
 | 
			
		||||
@@ -473,7 +473,7 @@ namespace FreeSql.Internal
 | 
			
		||||
                left = tmp;
 | 
			
		||||
            }
 | 
			
		||||
            if (right == "NULL") oper = oper == "=" ? " IS " : " IS NOT ";
 | 
			
		||||
            switch(oper)
 | 
			
		||||
            switch (oper)
 | 
			
		||||
            {
 | 
			
		||||
                case "%": return _common.Mod(left, right, leftExp.Type, rightExp.Type);
 | 
			
		||||
                case "AND":
 | 
			
		||||
@@ -647,6 +647,12 @@ namespace FreeSql.Internal
 | 
			
		||||
                                                Type = SelectTableInfoType.Parent,
 | 
			
		||||
                                                Parameter = a.Parameter
 | 
			
		||||
                                            }));
 | 
			
		||||
                                        if (tsc.whereCascadeExpression?.Any() == true)
 | 
			
		||||
                                        {
 | 
			
		||||
                                            var fsqlCascade = fsqlType.GetField("_whereCascadeExpression", BindingFlags.Instance | BindingFlags.NonPublic).GetValue(fsql) as List<LambdaExpression>;
 | 
			
		||||
                                            if (fsqlCascade != tsc.whereCascadeExpression)
 | 
			
		||||
                                                fsqlCascade.AddRange(tsc.whereCascadeExpression);
 | 
			
		||||
                                        }
 | 
			
		||||
                                    }
 | 
			
		||||
                                    else if (fsqlType != null)
 | 
			
		||||
                                    {
 | 
			
		||||
@@ -907,7 +913,8 @@ namespace FreeSql.Internal
 | 
			
		||||
                        }
 | 
			
		||||
                        var name = tb.ColumnsByCs[memberExp.Member.Name].Attribute.Name;
 | 
			
		||||
                        if (tsc.isQuoteName) name = _common.QuoteSqlName(name);
 | 
			
		||||
                        return name;
 | 
			
		||||
                        if (string.IsNullOrEmpty(tsc.alias001)) return name;
 | 
			
		||||
                        return $"{tsc.alias001}.{name}";
 | 
			
		||||
                    }
 | 
			
		||||
                    Func<TableInfo, string, bool, ParameterExpression, MemberExpression, SelectTableInfo> getOrAddTable = (tbtmp, alias, isa, parmExp, mp) =>
 | 
			
		||||
                    {
 | 
			
		||||
@@ -1113,6 +1120,8 @@ namespace FreeSql.Internal
 | 
			
		||||
            public ExpressionStyle style { get; set; }
 | 
			
		||||
            public Type mapType { get; set; }
 | 
			
		||||
            public TableInfo currentTable { get; set; }
 | 
			
		||||
            public List<LambdaExpression> whereCascadeExpression { get; set; }
 | 
			
		||||
            public string alias001 { get; set; } //单表字段的表别名
 | 
			
		||||
 | 
			
		||||
            public ExpTSC CloneSetgetSelectGroupingMapStringAndgetSelectGroupingMapStringAndtbtype(List<SelectColumnInfo> v1, Func<Expression[], string> v2, SelectTableInfoType v3)
 | 
			
		||||
            {
 | 
			
		||||
@@ -1125,7 +1134,9 @@ namespace FreeSql.Internal
 | 
			
		||||
                    isQuoteName = this.isQuoteName,
 | 
			
		||||
                    isDisableDiyParse = this.isDisableDiyParse,
 | 
			
		||||
                    style = this.style,
 | 
			
		||||
                    currentTable = this.currentTable
 | 
			
		||||
                    currentTable = this.currentTable,
 | 
			
		||||
                    whereCascadeExpression = this.whereCascadeExpression,
 | 
			
		||||
                    alias001 = this.alias001
 | 
			
		||||
                };
 | 
			
		||||
            }
 | 
			
		||||
            public ExpTSC CloneDisableDiyParse()
 | 
			
		||||
@@ -1139,11 +1150,46 @@ namespace FreeSql.Internal
 | 
			
		||||
                    isQuoteName = this.isQuoteName,
 | 
			
		||||
                    isDisableDiyParse = true,
 | 
			
		||||
                    style = this.style,
 | 
			
		||||
                    currentTable = this.currentTable
 | 
			
		||||
                    currentTable = this.currentTable,
 | 
			
		||||
                    whereCascadeExpression = this.whereCascadeExpression,
 | 
			
		||||
                    alias001 = this.alias001
 | 
			
		||||
                };
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        static ConcurrentDictionary<string, bool> _dicGetWhereCascadeSqlError = new ConcurrentDictionary<string, bool>();
 | 
			
		||||
        public string GetWhereCascadeSql(SelectTableInfo tb, List<LambdaExpression> _whereCascadeExpression)
 | 
			
		||||
        {
 | 
			
		||||
            if (_whereCascadeExpression.Any())
 | 
			
		||||
            {
 | 
			
		||||
                var newParameter = Expression.Parameter(tb.Table.Type, "c");
 | 
			
		||||
                Expression newExp = null;
 | 
			
		||||
 | 
			
		||||
                foreach (var fl in _whereCascadeExpression)
 | 
			
		||||
                {
 | 
			
		||||
                    var errorKey = FreeUtil.Sha1($"{tb.Table.Type.FullName},{fl.ToString()}");
 | 
			
		||||
                    if (_dicGetWhereCascadeSqlError.ContainsKey(errorKey)) continue;
 | 
			
		||||
 | 
			
		||||
                    var visitor = new NewExpressionVisitor(newParameter, fl.Parameters.FirstOrDefault());
 | 
			
		||||
                    try
 | 
			
		||||
                    {
 | 
			
		||||
                        var andExp = visitor.Replace(fl.Body);
 | 
			
		||||
                        if (newExp == null) newExp = andExp;
 | 
			
		||||
                        else newExp = Expression.AndAlso(newExp, andExp);
 | 
			
		||||
                    }
 | 
			
		||||
                    catch
 | 
			
		||||
                    {
 | 
			
		||||
                        _dicGetWhereCascadeSqlError.TryAdd(errorKey, true);
 | 
			
		||||
                        continue;
 | 
			
		||||
                    }
 | 
			
		||||
                }
 | 
			
		||||
 | 
			
		||||
                if (newExp != null)
 | 
			
		||||
                    return ExpressionLambdaToSql(newExp, new ExpTSC { _tables = null, _selectColumnMap = null, getSelectGroupingMapString = null, tbtype = SelectTableInfoType.From, isQuoteName = true, isDisableDiyParse = false, style = ExpressionStyle.Where, currentTable = tb.Table, alias001 = tb.Alias });
 | 
			
		||||
            }
 | 
			
		||||
            return null;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        public string formatSql(object obj, Type mapType)
 | 
			
		||||
        {
 | 
			
		||||
            return string.Concat(_ado.AddslashesProcessParam(obj, mapType));
 | 
			
		||||
 
 | 
			
		||||
@@ -31,10 +31,26 @@ namespace FreeSql.Internal.CommonProvider
 | 
			
		||||
        protected DbTransaction _transaction;
 | 
			
		||||
        protected DbConnection _connection;
 | 
			
		||||
        protected Action<object> _trackToList;
 | 
			
		||||
        protected Queue<Action<object>> _includeToList = new Queue<Action<object>>();
 | 
			
		||||
        protected List<Action<object>> _includeToList = new List<Action<object>>();
 | 
			
		||||
        protected bool _distinct;
 | 
			
		||||
        protected Expression _selectExpression;
 | 
			
		||||
        protected List<LambdaExpression> _whereCascadeExpression = new List<LambdaExpression>();
 | 
			
		||||
 | 
			
		||||
        bool _isDisponse = false;
 | 
			
		||||
        ~Select0Provider()
 | 
			
		||||
        {
 | 
			
		||||
            if (_isDisponse) return;
 | 
			
		||||
            _isDisponse = false;
 | 
			
		||||
            _where.Clear();
 | 
			
		||||
            _params.Clear();
 | 
			
		||||
            _tables.Clear();
 | 
			
		||||
            _tableRules.Clear();
 | 
			
		||||
            _join.Clear();
 | 
			
		||||
            _trackToList = null;
 | 
			
		||||
            _includeToList.Clear();
 | 
			
		||||
            _selectExpression = null;
 | 
			
		||||
            _whereCascadeExpression.Clear();
 | 
			
		||||
        }
 | 
			
		||||
        public static void CopyData(Select0Provider<TSelect, T1> from, object to, ReadOnlyCollection<ParameterExpression> lambParms)
 | 
			
		||||
        {
 | 
			
		||||
            var toType = to?.GetType();
 | 
			
		||||
@@ -77,6 +93,7 @@ namespace FreeSql.Internal.CommonProvider
 | 
			
		||||
            toType.GetField("_includeToList", BindingFlags.Instance | BindingFlags.NonPublic)?.SetValue(to, from._includeToList);
 | 
			
		||||
            toType.GetField("_distinct", BindingFlags.Instance | BindingFlags.NonPublic)?.SetValue(to, from._distinct);
 | 
			
		||||
            toType.GetField("_selectExpression", BindingFlags.Instance | BindingFlags.NonPublic)?.SetValue(to, from._selectExpression);
 | 
			
		||||
            toType.GetField("_whereMultiExpression", BindingFlags.Instance | BindingFlags.NonPublic)?.SetValue(to, from._whereCascadeExpression);
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        public Select0Provider(IFreeSql orm, CommonUtils commonUtils, CommonExpression commonExpression, object dywhere)
 | 
			
		||||
@@ -384,7 +401,7 @@ namespace FreeSql.Internal.CommonProvider
 | 
			
		||||
                var after = new Aop.CurdAfterEventArgs(before, exception, ret);
 | 
			
		||||
                _orm.Aop.CurdAfter?.Invoke(this, after);
 | 
			
		||||
            }
 | 
			
		||||
            while (_includeToList.Any()) _includeToList.Dequeue()?.Invoke(ret);
 | 
			
		||||
            foreach (var include in _includeToList) include?.Invoke(ret);
 | 
			
		||||
            _orm.Aop.ToList?.Invoke(this, new Aop.ToListEventArgs(ret));
 | 
			
		||||
            _trackToList?.Invoke(ret);
 | 
			
		||||
            return ret;
 | 
			
		||||
@@ -420,7 +437,7 @@ namespace FreeSql.Internal.CommonProvider
 | 
			
		||||
                var after = new Aop.CurdAfterEventArgs(before, exception, ret);
 | 
			
		||||
                _orm.Aop.CurdAfter?.Invoke(this, after);
 | 
			
		||||
            }
 | 
			
		||||
            while (_includeToList.Any()) _includeToList.Dequeue()?.Invoke(ret);
 | 
			
		||||
            foreach (var include in _includeToList) include?.Invoke(ret);
 | 
			
		||||
            _orm.Aop.ToList?.Invoke(this, new Aop.ToListEventArgs(ret));
 | 
			
		||||
            _trackToList?.Invoke(ret);
 | 
			
		||||
            return ret;
 | 
			
		||||
@@ -548,7 +565,7 @@ namespace FreeSql.Internal.CommonProvider
 | 
			
		||||
            var field = new StringBuilder();
 | 
			
		||||
            var index = 0;
 | 
			
		||||
 | 
			
		||||
            _commonExpression.ReadAnonymousField(_tables, field, map, ref index, newexp, null);
 | 
			
		||||
            _commonExpression.ReadAnonymousField(_tables, field, map, ref index, newexp, null, _whereCascadeExpression);
 | 
			
		||||
            return (map, field.Length > 0 ? field.Remove(0, 2).ToString() : null);
 | 
			
		||||
        }
 | 
			
		||||
        static ConcurrentDictionary<Type, ConstructorInfo> _dicConstructor = new ConcurrentDictionary<Type, ConstructorInfo>();
 | 
			
		||||
@@ -944,13 +961,13 @@ namespace FreeSql.Internal.CommonProvider
 | 
			
		||||
            var field = new StringBuilder();
 | 
			
		||||
            var index = -10000; //临时规则,不返回 as1
 | 
			
		||||
 | 
			
		||||
            _commonExpression.ReadAnonymousField(_tables, field, map, ref index, columns, null);
 | 
			
		||||
            _commonExpression.ReadAnonymousField(_tables, field, map, ref index, columns, null, _whereCascadeExpression);
 | 
			
		||||
            this.GroupBy(field.Length > 0 ? field.Remove(0, 2).ToString() : null);
 | 
			
		||||
            return new SelectGroupingProvider<TKey, TValue>(this, map, _commonExpression, _tables);
 | 
			
		||||
        }
 | 
			
		||||
        protected TSelect InternalJoin(Expression exp, SelectTableInfoType joinType)
 | 
			
		||||
        {
 | 
			
		||||
            _commonExpression.ExpressionJoinLambda(_tables, joinType, exp, null);
 | 
			
		||||
            _commonExpression.ExpressionJoinLambda(_tables, joinType, exp, null, _whereCascadeExpression);
 | 
			
		||||
            return this as TSelect;
 | 
			
		||||
        }
 | 
			
		||||
        protected TSelect InternalJoin<T2>(Expression exp, SelectTableInfoType joinType)
 | 
			
		||||
@@ -958,7 +975,7 @@ namespace FreeSql.Internal.CommonProvider
 | 
			
		||||
            var tb = _commonUtils.GetTableByEntity(typeof(T2));
 | 
			
		||||
            if (tb == null) throw new ArgumentException("T2 类型错误");
 | 
			
		||||
            _tables.Add(new SelectTableInfo { Table = tb, Alias = $"IJ{_tables.Count}", On = null, Type = joinType });
 | 
			
		||||
            _commonExpression.ExpressionJoinLambda(_tables, joinType, exp, null);
 | 
			
		||||
            _commonExpression.ExpressionJoinLambda(_tables, joinType, exp, null, _whereCascadeExpression);
 | 
			
		||||
            return this as TSelect;
 | 
			
		||||
        }
 | 
			
		||||
        protected TSelect InternalOrderBy(Expression column) => this.OrderBy(_commonExpression.ExpressionSelectColumn_MemberAccess(_tables, null, SelectTableInfoType.From, column, true, null));
 | 
			
		||||
@@ -1027,7 +1044,7 @@ namespace FreeSql.Internal.CommonProvider
 | 
			
		||||
            var field = new StringBuilder();
 | 
			
		||||
            var index = 0;
 | 
			
		||||
 | 
			
		||||
            _commonExpression.ReadAnonymousField(_tables, field, map, ref index, select, null);
 | 
			
		||||
            _commonExpression.ReadAnonymousField(_tables, field, map, ref index, select, null, _whereCascadeExpression);
 | 
			
		||||
            return this.ToListMapReader<TReturn>((map, field.Length > 0 ? field.Remove(0, 2).ToString() : null)).FirstOrDefault();
 | 
			
		||||
        }
 | 
			
		||||
        async protected Task<TReturn> InternalToAggregateAsync<TReturn>(Expression select)
 | 
			
		||||
@@ -1036,11 +1053,11 @@ namespace FreeSql.Internal.CommonProvider
 | 
			
		||||
            var field = new StringBuilder();
 | 
			
		||||
            var index = 0;
 | 
			
		||||
 | 
			
		||||
            _commonExpression.ReadAnonymousField(_tables, field, map, ref index, select, null);
 | 
			
		||||
            _commonExpression.ReadAnonymousField(_tables, field, map, ref index, select, null, _whereCascadeExpression);
 | 
			
		||||
            return (await this.ToListMapReaderAsync<TReturn>((map, field.Length > 0 ? field.Remove(0, 2).ToString() : null))).FirstOrDefault();
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        protected TSelect InternalWhere(Expression exp) => exp == null ? this as TSelect : this.Where(_commonExpression.ExpressionWhereLambda(_tables, exp, null));
 | 
			
		||||
        protected TSelect InternalWhere(Expression exp) => exp == null ? this as TSelect : this.Where(_commonExpression.ExpressionWhereLambda(_tables, exp, null, _whereCascadeExpression));
 | 
			
		||||
        #endregion
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
@@ -181,28 +181,28 @@ namespace FreeSql.Internal.CommonProvider
 | 
			
		||||
        {
 | 
			
		||||
            if (exp == null) return this.Where(null);
 | 
			
		||||
            for (var a = 0; a < exp.Parameters.Count; a++) _tables[a].Parameter = exp.Parameters[a];
 | 
			
		||||
            return this.Where(_commonExpression.ExpressionWhereLambda(_tables, exp?.Body, null));
 | 
			
		||||
            return this.Where(_commonExpression.ExpressionWhereLambda(_tables, exp?.Body, null, _whereCascadeExpression));
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        ISelect<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10> ISelect<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10>.WhereIf(bool condition, Expression<Func<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, bool>> exp)
 | 
			
		||||
        {
 | 
			
		||||
            if (condition == false || exp == null) return this.Where(null);
 | 
			
		||||
            for (var a = 0; a < exp.Parameters.Count; a++) _tables[a].Parameter = exp.Parameters[a];
 | 
			
		||||
            return condition ? this.Where(_commonExpression.ExpressionWhereLambda(_tables, exp?.Body, null)) : this;
 | 
			
		||||
            return condition ? this.Where(_commonExpression.ExpressionWhereLambda(_tables, exp?.Body, null, _whereCascadeExpression)) : this;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        bool ISelect<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10>.Any(Expression<Func<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, bool>> exp)
 | 
			
		||||
        {
 | 
			
		||||
            if (exp == null) return this.Any();
 | 
			
		||||
            for (var a = 0; a < exp.Parameters.Count; a++) _tables[a].Parameter = exp.Parameters[a];
 | 
			
		||||
            return this.Where(_commonExpression.ExpressionWhereLambda(_tables, exp?.Body, null)).Any();
 | 
			
		||||
            return this.Where(_commonExpression.ExpressionWhereLambda(_tables, exp?.Body, null, _whereCascadeExpression)).Any();
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        Task<bool> ISelect<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10>.AnyAsync(Expression<Func<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, bool>> exp)
 | 
			
		||||
        {
 | 
			
		||||
            if (exp == null) return this.AnyAsync();
 | 
			
		||||
            for (var a = 0; a < exp.Parameters.Count; a++) _tables[a].Parameter = exp.Parameters[a];
 | 
			
		||||
            return this.Where(_commonExpression.ExpressionWhereLambda(_tables, exp?.Body, null)).AnyAsync();
 | 
			
		||||
            return this.Where(_commonExpression.ExpressionWhereLambda(_tables, exp?.Body, null, _whereCascadeExpression)).AnyAsync();
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
@@ -321,9 +321,10 @@ namespace FreeSql.Internal.CommonProvider
 | 
			
		||||
            return this.InternalToAggregateAsync<TReturn>(select?.Body);
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        public ISelect<T1> Where(Expression<Func<T1, bool>> exp)
 | 
			
		||||
        public ISelect<T1> Where(Expression<Func<T1, bool>> exp) => WhereIf(true, exp);
 | 
			
		||||
        public ISelect<T1> WhereIf(bool condition, Expression<Func<T1, bool>> exp)
 | 
			
		||||
        {
 | 
			
		||||
            if (exp == null) return this;
 | 
			
		||||
            if (condition == false || exp == null) return this;
 | 
			
		||||
            _tables[0].Parameter = exp.Parameters[0];
 | 
			
		||||
            return this.InternalWhere(exp?.Body);
 | 
			
		||||
        }
 | 
			
		||||
@@ -364,11 +365,10 @@ namespace FreeSql.Internal.CommonProvider
 | 
			
		||||
        }
 | 
			
		||||
        public ISelect<T1> WhereDynamic(object dywhere) => this.Where(_commonUtils.WhereObject(_tables.First().Table, $"{_tables.First().Alias}.", dywhere));
 | 
			
		||||
 | 
			
		||||
        public ISelect<T1> WhereIf(bool condition, Expression<Func<T1, bool>> exp)
 | 
			
		||||
        public ISelect<T1> WhereCascade(Expression<Func<T1, bool>> exp)
 | 
			
		||||
        {
 | 
			
		||||
            if (condition == false || exp == null) return this;
 | 
			
		||||
            _tables[0].Parameter = exp.Parameters[0];
 | 
			
		||||
            return this.InternalWhere(exp?.Body);
 | 
			
		||||
            if (exp != null) _whereCascadeExpression.Add(exp);
 | 
			
		||||
            return this;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        public bool Any(Expression<Func<T1, bool>> exp) => this.Where(exp).Any();
 | 
			
		||||
@@ -390,7 +390,7 @@ namespace FreeSql.Internal.CommonProvider
 | 
			
		||||
            var tb = _commonUtils.GetTableByEntity(expBody.Type);
 | 
			
		||||
            if (tb == null) throw new Exception("Include 参数类型错误");
 | 
			
		||||
 | 
			
		||||
            _commonExpression.ExpressionWhereLambda(_tables, Expression.MakeMemberAccess(expBody, tb.Properties[tb.ColumnsByCs.First().Value.CsName]), null);
 | 
			
		||||
            _commonExpression.ExpressionWhereLambda(_tables, Expression.MakeMemberAccess(expBody, tb.Properties[tb.ColumnsByCs.First().Value.CsName]), null, null);
 | 
			
		||||
            return this;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
@@ -454,15 +454,13 @@ namespace FreeSql.Internal.CommonProvider
 | 
			
		||||
            if (tbNav == null) throw new Exception($"类型 {typeof(TNavigate).FullName} 错误,不能使用 IncludeMany");
 | 
			
		||||
 | 
			
		||||
            if (collMem.Expression.NodeType != ExpressionType.Parameter)
 | 
			
		||||
                _commonExpression.ExpressionWhereLambda(_tables, Expression.MakeMemberAccess(collMem.Expression, tb.Properties[tb.ColumnsByCs.First().Value.CsName]), null);
 | 
			
		||||
                _commonExpression.ExpressionWhereLambda(_tables, Expression.MakeMemberAccess(collMem.Expression, tb.Properties[tb.ColumnsByCs.First().Value.CsName]), null, null);
 | 
			
		||||
 | 
			
		||||
            TableRef tbref = null;
 | 
			
		||||
            var tbrefOneToManyColumns = new List<List<MemberExpression>>(); //临时 OneToMany 三个表关联,第三个表需要前两个表确定
 | 
			
		||||
            if (whereExp == null)
 | 
			
		||||
            {
 | 
			
		||||
 | 
			
		||||
                tbref = tb.GetTableRef(collMem.Member.Name, true);
 | 
			
		||||
 | 
			
		||||
            }
 | 
			
		||||
            else
 | 
			
		||||
            {
 | 
			
		||||
@@ -563,8 +561,8 @@ namespace FreeSql.Internal.CommonProvider
 | 
			
		||||
                }
 | 
			
		||||
                if (tbref.Columns.Any() == false) throw throwNavigateSelector;
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
            _includeToList.Enqueue(listObj =>
 | 
			
		||||
            
 | 
			
		||||
            _includeToList.Add(listObj =>
 | 
			
		||||
            {
 | 
			
		||||
                var list = listObj as List<T1>;
 | 
			
		||||
                if (list == null) return;
 | 
			
		||||
@@ -621,6 +619,10 @@ namespace FreeSql.Internal.CommonProvider
 | 
			
		||||
                var subSelect = _orm.Select<TNavigate>().WithConnection(_connection).WithTransaction(_transaction).TrackToList(_trackToList) as Select1Provider<TNavigate>;
 | 
			
		||||
                if (_tableRules?.Any() == true)
 | 
			
		||||
                    foreach (var tr in _tableRules) subSelect.AsTable(tr);
 | 
			
		||||
 | 
			
		||||
                if (_whereCascadeExpression.Any())
 | 
			
		||||
                    subSelect._whereCascadeExpression.AddRange(_whereCascadeExpression.ToArray());
 | 
			
		||||
 | 
			
		||||
                then?.Invoke(subSelect);
 | 
			
		||||
                var subSelectT1Alias = subSelect._tables[0].Alias;
 | 
			
		||||
                var oldWhere = subSelect._where.ToString();
 | 
			
		||||
@@ -778,6 +780,11 @@ namespace FreeSql.Internal.CommonProvider
 | 
			
		||||
                            {
 | 
			
		||||
                                if (z > 0) sbJoin.Append(" AND ");
 | 
			
		||||
                                sbJoin.Append($"midtb.{_commonUtils.QuoteSqlName(tbref.MiddleColumns[tbref.Columns.Count + z].Attribute.Name)} = a.{_commonUtils.QuoteSqlName(tbref.RefColumns[z].Attribute.Name)}");
 | 
			
		||||
                                if (_whereCascadeExpression.Any()) {
 | 
			
		||||
                                    var cascade = _commonExpression.GetWhereCascadeSql(new SelectTableInfo { Alias = "midtb", AliasInit = "midtb", Table = tbrefMid, Type = SelectTableInfoType.InnerJoin }, _whereCascadeExpression);
 | 
			
		||||
                                    if (string.IsNullOrEmpty(cascade) == false)
 | 
			
		||||
                                        sbJoin.Append(" AND (").Append(cascade).Append(")");
 | 
			
		||||
                                }
 | 
			
		||||
                            }
 | 
			
		||||
                            subSelect.InnerJoin(sbJoin.ToString());
 | 
			
		||||
                            sbJoin.Clear();
 | 
			
		||||
 
 | 
			
		||||
@@ -157,28 +157,28 @@ namespace FreeSql.Internal.CommonProvider
 | 
			
		||||
        {
 | 
			
		||||
            if (exp == null) return this.Where(null);
 | 
			
		||||
            for (var a = 0; a < exp.Parameters.Count; a++) _tables[a].Parameter = exp.Parameters[a];
 | 
			
		||||
            return this.Where(_commonExpression.ExpressionWhereLambda(_tables, exp?.Body, null));
 | 
			
		||||
            return this.Where(_commonExpression.ExpressionWhereLambda(_tables, exp?.Body, null, _whereCascadeExpression));
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        ISelect<T1, T2> ISelect<T1, T2>.WhereIf(bool condition, Expression<Func<T1, T2, bool>> exp)
 | 
			
		||||
        {
 | 
			
		||||
            if (condition == false || exp == null) return this;
 | 
			
		||||
            for (var a = 0; a < exp.Parameters.Count; a++) _tables[a].Parameter = exp.Parameters[a];
 | 
			
		||||
            return this.Where(_commonExpression.ExpressionWhereLambda(_tables, exp?.Body, null));
 | 
			
		||||
            return this.Where(_commonExpression.ExpressionWhereLambda(_tables, exp?.Body, null, _whereCascadeExpression));
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        bool ISelect<T1, T2>.Any(Expression<Func<T1, T2, bool>> exp)
 | 
			
		||||
        {
 | 
			
		||||
            if (exp == null) return this.Any();
 | 
			
		||||
            for (var a = 0; a < exp.Parameters.Count; a++) _tables[a].Parameter = exp.Parameters[a];
 | 
			
		||||
            return this.Where(_commonExpression.ExpressionWhereLambda(_tables, exp?.Body, null)).Any();
 | 
			
		||||
            return this.Where(_commonExpression.ExpressionWhereLambda(_tables, exp?.Body, null, _whereCascadeExpression)).Any();
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        Task<bool> ISelect<T1, T2>.AnyAsync(Expression<Func<T1, T2, bool>> exp)
 | 
			
		||||
        {
 | 
			
		||||
            if (exp == null) return this.AnyAsync();
 | 
			
		||||
            for (var a = 0; a < exp.Parameters.Count; a++) _tables[a].Parameter = exp.Parameters[a];
 | 
			
		||||
            return this.Where(_commonExpression.ExpressionWhereLambda(_tables, exp?.Body, null)).AnyAsync();
 | 
			
		||||
            return this.Where(_commonExpression.ExpressionWhereLambda(_tables, exp?.Body, null, _whereCascadeExpression)).AnyAsync();
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
@@ -160,28 +160,28 @@ namespace FreeSql.Internal.CommonProvider
 | 
			
		||||
        {
 | 
			
		||||
            if (exp == null) return this.Where(null);
 | 
			
		||||
            for (var a = 0; a < exp.Parameters.Count; a++) _tables[a].Parameter = exp.Parameters[a];
 | 
			
		||||
            return this.Where(_commonExpression.ExpressionWhereLambda(_tables, exp?.Body, null));
 | 
			
		||||
            return this.Where(_commonExpression.ExpressionWhereLambda(_tables, exp?.Body, null, _whereCascadeExpression));
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        ISelect<T1, T2, T3> ISelect<T1, T2, T3>.WhereIf(bool condition, Expression<Func<T1, T2, T3, bool>> exp)
 | 
			
		||||
        {
 | 
			
		||||
            if (condition == false || exp == null) return this;
 | 
			
		||||
            for (var a = 0; a < exp.Parameters.Count; a++) _tables[a].Parameter = exp.Parameters[a];
 | 
			
		||||
            return this.Where(_commonExpression.ExpressionWhereLambda(_tables, exp?.Body, null));
 | 
			
		||||
            return this.Where(_commonExpression.ExpressionWhereLambda(_tables, exp?.Body, null, _whereCascadeExpression));
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        bool ISelect<T1, T2, T3>.Any(Expression<Func<T1, T2, T3, bool>> exp)
 | 
			
		||||
        {
 | 
			
		||||
            if (exp == null) return this.Any();
 | 
			
		||||
            for (var a = 0; a < exp.Parameters.Count; a++) _tables[a].Parameter = exp.Parameters[a];
 | 
			
		||||
            return this.Where(_commonExpression.ExpressionWhereLambda(_tables, exp?.Body, null)).Any();
 | 
			
		||||
            return this.Where(_commonExpression.ExpressionWhereLambda(_tables, exp?.Body, null, _whereCascadeExpression)).Any();
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        Task<bool> ISelect<T1, T2, T3>.AnyAsync(Expression<Func<T1, T2, T3, bool>> exp)
 | 
			
		||||
        {
 | 
			
		||||
            if (exp == null) return this.AnyAsync();
 | 
			
		||||
            for (var a = 0; a < exp.Parameters.Count; a++) _tables[a].Parameter = exp.Parameters[a];
 | 
			
		||||
            return this.Where(_commonExpression.ExpressionWhereLambda(_tables, exp?.Body, null)).AnyAsync();
 | 
			
		||||
            return this.Where(_commonExpression.ExpressionWhereLambda(_tables, exp?.Body, null, _whereCascadeExpression)).AnyAsync();
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
@@ -163,28 +163,28 @@ namespace FreeSql.Internal.CommonProvider
 | 
			
		||||
        {
 | 
			
		||||
            if (exp == null) return this.Where(null);
 | 
			
		||||
            for (var a = 0; a < exp.Parameters.Count; a++) _tables[a].Parameter = exp.Parameters[a];
 | 
			
		||||
            return this.Where(_commonExpression.ExpressionWhereLambda(_tables, exp?.Body, null));
 | 
			
		||||
            return this.Where(_commonExpression.ExpressionWhereLambda(_tables, exp?.Body, null, _whereCascadeExpression));
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        ISelect<T1, T2, T3, T4> ISelect<T1, T2, T3, T4>.WhereIf(bool condition, Expression<Func<T1, T2, T3, T4, bool>> exp)
 | 
			
		||||
        {
 | 
			
		||||
            if (condition == false || exp == null) return this;
 | 
			
		||||
            for (var a = 0; a < exp.Parameters.Count; a++) _tables[a].Parameter = exp.Parameters[a];
 | 
			
		||||
            return this.Where(_commonExpression.ExpressionWhereLambda(_tables, exp?.Body, null));
 | 
			
		||||
            return this.Where(_commonExpression.ExpressionWhereLambda(_tables, exp?.Body, null, _whereCascadeExpression));
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        bool ISelect<T1, T2, T3, T4>.Any(Expression<Func<T1, T2, T3, T4, bool>> exp)
 | 
			
		||||
        {
 | 
			
		||||
            if (exp == null) return this.Any();
 | 
			
		||||
            for (var a = 0; a < exp.Parameters.Count; a++) _tables[a].Parameter = exp.Parameters[a];
 | 
			
		||||
            return this.Where(_commonExpression.ExpressionWhereLambda(_tables, exp?.Body, null)).Any();
 | 
			
		||||
            return this.Where(_commonExpression.ExpressionWhereLambda(_tables, exp?.Body, null, _whereCascadeExpression)).Any();
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        Task<bool> ISelect<T1, T2, T3, T4>.AnyAsync(Expression<Func<T1, T2, T3, T4, bool>> exp)
 | 
			
		||||
        {
 | 
			
		||||
            if (exp == null) return this.AnyAsync();
 | 
			
		||||
            for (var a = 0; a < exp.Parameters.Count; a++) _tables[a].Parameter = exp.Parameters[a];
 | 
			
		||||
            return this.Where(_commonExpression.ExpressionWhereLambda(_tables, exp?.Body, null)).AnyAsync();
 | 
			
		||||
            return this.Where(_commonExpression.ExpressionWhereLambda(_tables, exp?.Body, null, _whereCascadeExpression)).AnyAsync();
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
@@ -166,28 +166,28 @@ namespace FreeSql.Internal.CommonProvider
 | 
			
		||||
        {
 | 
			
		||||
            if (exp == null) return this.Where(null);
 | 
			
		||||
            for (var a = 0; a < exp.Parameters.Count; a++) _tables[a].Parameter = exp.Parameters[a];
 | 
			
		||||
            return this.Where(_commonExpression.ExpressionWhereLambda(_tables, exp?.Body, null));
 | 
			
		||||
            return this.Where(_commonExpression.ExpressionWhereLambda(_tables, exp?.Body, null, _whereCascadeExpression));
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        ISelect<T1, T2, T3, T4, T5> ISelect<T1, T2, T3, T4, T5>.WhereIf(bool condition, Expression<Func<T1, T2, T3, T4, T5, bool>> exp)
 | 
			
		||||
        {
 | 
			
		||||
            if (condition == false || exp == null) return this;
 | 
			
		||||
            for (var a = 0; a < exp.Parameters.Count; a++) _tables[a].Parameter = exp.Parameters[a];
 | 
			
		||||
            return this.Where(_commonExpression.ExpressionWhereLambda(_tables, exp?.Body, null));
 | 
			
		||||
            return this.Where(_commonExpression.ExpressionWhereLambda(_tables, exp?.Body, null, _whereCascadeExpression));
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        bool ISelect<T1, T2, T3, T4, T5>.Any(Expression<Func<T1, T2, T3, T4, T5, bool>> exp)
 | 
			
		||||
        {
 | 
			
		||||
            if (exp == null) return this.Any();
 | 
			
		||||
            for (var a = 0; a < exp.Parameters.Count; a++) _tables[a].Parameter = exp.Parameters[a];
 | 
			
		||||
            return this.Where(_commonExpression.ExpressionWhereLambda(_tables, exp?.Body, null)).Any();
 | 
			
		||||
            return this.Where(_commonExpression.ExpressionWhereLambda(_tables, exp?.Body, null, _whereCascadeExpression)).Any();
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        Task<bool> ISelect<T1, T2, T3, T4, T5>.AnyAsync(Expression<Func<T1, T2, T3, T4, T5, bool>> exp)
 | 
			
		||||
        {
 | 
			
		||||
            if (exp == null) return this.AnyAsync();
 | 
			
		||||
            for (var a = 0; a < exp.Parameters.Count; a++) _tables[a].Parameter = exp.Parameters[a];
 | 
			
		||||
            return this.Where(_commonExpression.ExpressionWhereLambda(_tables, exp?.Body, null)).AnyAsync();
 | 
			
		||||
            return this.Where(_commonExpression.ExpressionWhereLambda(_tables, exp?.Body, null, _whereCascadeExpression)).AnyAsync();
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
@@ -169,28 +169,28 @@ namespace FreeSql.Internal.CommonProvider
 | 
			
		||||
        {
 | 
			
		||||
            if (exp == null) return this.Where(null);
 | 
			
		||||
            for (var a = 0; a < exp.Parameters.Count; a++) _tables[a].Parameter = exp.Parameters[a];
 | 
			
		||||
            return this.Where(_commonExpression.ExpressionWhereLambda(_tables, exp?.Body, null));
 | 
			
		||||
            return this.Where(_commonExpression.ExpressionWhereLambda(_tables, exp?.Body, null, _whereCascadeExpression));
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        ISelect<T1, T2, T3, T4, T5, T6> ISelect<T1, T2, T3, T4, T5, T6>.WhereIf(bool condition, Expression<Func<T1, T2, T3, T4, T5, T6, bool>> exp)
 | 
			
		||||
        {
 | 
			
		||||
            if (condition == false || exp == null) return this;
 | 
			
		||||
            for (var a = 0; a < exp.Parameters.Count; a++) _tables[a].Parameter = exp.Parameters[a];
 | 
			
		||||
            return this.Where(_commonExpression.ExpressionWhereLambda(_tables, exp?.Body, null));
 | 
			
		||||
            return this.Where(_commonExpression.ExpressionWhereLambda(_tables, exp?.Body, null, _whereCascadeExpression));
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        bool ISelect<T1, T2, T3, T4, T5, T6>.Any(Expression<Func<T1, T2, T3, T4, T5, T6, bool>> exp)
 | 
			
		||||
        {
 | 
			
		||||
            if (exp == null) return this.Any();
 | 
			
		||||
            for (var a = 0; a < exp.Parameters.Count; a++) _tables[a].Parameter = exp.Parameters[a];
 | 
			
		||||
            return this.Where(_commonExpression.ExpressionWhereLambda(_tables, exp?.Body, null)).Any();
 | 
			
		||||
            return this.Where(_commonExpression.ExpressionWhereLambda(_tables, exp?.Body, null, _whereCascadeExpression)).Any();
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        Task<bool> ISelect<T1, T2, T3, T4, T5, T6>.AnyAsync(Expression<Func<T1, T2, T3, T4, T5, T6, bool>> exp)
 | 
			
		||||
        {
 | 
			
		||||
            if (exp == null) return this.AnyAsync();
 | 
			
		||||
            for (var a = 0; a < exp.Parameters.Count; a++) _tables[a].Parameter = exp.Parameters[a];
 | 
			
		||||
            return this.Where(_commonExpression.ExpressionWhereLambda(_tables, exp?.Body, null)).AnyAsync();
 | 
			
		||||
            return this.Where(_commonExpression.ExpressionWhereLambda(_tables, exp?.Body, null, _whereCascadeExpression)).AnyAsync();
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
@@ -172,28 +172,28 @@ namespace FreeSql.Internal.CommonProvider
 | 
			
		||||
        {
 | 
			
		||||
            if (exp == null) return this.Where(null);
 | 
			
		||||
            for (var a = 0; a < exp.Parameters.Count; a++) _tables[a].Parameter = exp.Parameters[a];
 | 
			
		||||
            return this.Where(_commonExpression.ExpressionWhereLambda(_tables, exp?.Body, null));
 | 
			
		||||
            return this.Where(_commonExpression.ExpressionWhereLambda(_tables, exp?.Body, null, _whereCascadeExpression));
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        ISelect<T1, T2, T3, T4, T5, T6, T7> ISelect<T1, T2, T3, T4, T5, T6, T7>.WhereIf(bool condition, Expression<Func<T1, T2, T3, T4, T5, T6, T7, bool>> exp)
 | 
			
		||||
        {
 | 
			
		||||
            if (condition == false || exp == null) return this;
 | 
			
		||||
            for (var a = 0; a < exp.Parameters.Count; a++) _tables[a].Parameter = exp.Parameters[a];
 | 
			
		||||
            return this.Where(_commonExpression.ExpressionWhereLambda(_tables, exp?.Body, null));
 | 
			
		||||
            return this.Where(_commonExpression.ExpressionWhereLambda(_tables, exp?.Body, null, _whereCascadeExpression));
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        bool ISelect<T1, T2, T3, T4, T5, T6, T7>.Any(Expression<Func<T1, T2, T3, T4, T5, T6, T7, bool>> exp)
 | 
			
		||||
        {
 | 
			
		||||
            if (exp == null) return this.Any();
 | 
			
		||||
            for (var a = 0; a < exp.Parameters.Count; a++) _tables[a].Parameter = exp.Parameters[a];
 | 
			
		||||
            return this.Where(_commonExpression.ExpressionWhereLambda(_tables, exp?.Body, null)).Any();
 | 
			
		||||
            return this.Where(_commonExpression.ExpressionWhereLambda(_tables, exp?.Body, null, _whereCascadeExpression)).Any();
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        Task<bool> ISelect<T1, T2, T3, T4, T5, T6, T7>.AnyAsync(Expression<Func<T1, T2, T3, T4, T5, T6, T7, bool>> exp)
 | 
			
		||||
        {
 | 
			
		||||
            if (exp == null) return this.AnyAsync();
 | 
			
		||||
            for (var a = 0; a < exp.Parameters.Count; a++) _tables[a].Parameter = exp.Parameters[a];
 | 
			
		||||
            return this.Where(_commonExpression.ExpressionWhereLambda(_tables, exp?.Body, null)).AnyAsync();
 | 
			
		||||
            return this.Where(_commonExpression.ExpressionWhereLambda(_tables, exp?.Body, null, _whereCascadeExpression)).AnyAsync();
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
@@ -175,28 +175,28 @@ namespace FreeSql.Internal.CommonProvider
 | 
			
		||||
        {
 | 
			
		||||
            if (exp == null) return this.Where(null);
 | 
			
		||||
            for (var a = 0; a < exp.Parameters.Count; a++) _tables[a].Parameter = exp.Parameters[a];
 | 
			
		||||
            return this.Where(_commonExpression.ExpressionWhereLambda(_tables, exp?.Body, null));
 | 
			
		||||
            return this.Where(_commonExpression.ExpressionWhereLambda(_tables, exp?.Body, null, _whereCascadeExpression));
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        ISelect<T1, T2, T3, T4, T5, T6, T7, T8> ISelect<T1, T2, T3, T4, T5, T6, T7, T8>.WhereIf(bool condition, Expression<Func<T1, T2, T3, T4, T5, T6, T7, T8, bool>> exp)
 | 
			
		||||
        {
 | 
			
		||||
            if (condition == false || exp == null) return this;
 | 
			
		||||
            for (var a = 0; a < exp.Parameters.Count; a++) _tables[a].Parameter = exp.Parameters[a];
 | 
			
		||||
            return this.Where(_commonExpression.ExpressionWhereLambda(_tables, exp?.Body, null));
 | 
			
		||||
            return this.Where(_commonExpression.ExpressionWhereLambda(_tables, exp?.Body, null, _whereCascadeExpression));
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        bool ISelect<T1, T2, T3, T4, T5, T6, T7, T8>.Any(Expression<Func<T1, T2, T3, T4, T5, T6, T7, T8, bool>> exp)
 | 
			
		||||
        {
 | 
			
		||||
            if (exp == null) return this.Any();
 | 
			
		||||
            for (var a = 0; a < exp.Parameters.Count; a++) _tables[a].Parameter = exp.Parameters[a];
 | 
			
		||||
            return this.Where(_commonExpression.ExpressionWhereLambda(_tables, exp?.Body, null)).Any();
 | 
			
		||||
            return this.Where(_commonExpression.ExpressionWhereLambda(_tables, exp?.Body, null, _whereCascadeExpression)).Any();
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        Task<bool> ISelect<T1, T2, T3, T4, T5, T6, T7, T8>.AnyAsync(Expression<Func<T1, T2, T3, T4, T5, T6, T7, T8, bool>> exp)
 | 
			
		||||
        {
 | 
			
		||||
            if (exp == null) return this.AnyAsync();
 | 
			
		||||
            for (var a = 0; a < exp.Parameters.Count; a++) _tables[a].Parameter = exp.Parameters[a];
 | 
			
		||||
            return this.Where(_commonExpression.ExpressionWhereLambda(_tables, exp?.Body, null)).AnyAsync();
 | 
			
		||||
            return this.Where(_commonExpression.ExpressionWhereLambda(_tables, exp?.Body, null, _whereCascadeExpression)).AnyAsync();
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
@@ -178,28 +178,28 @@ namespace FreeSql.Internal.CommonProvider
 | 
			
		||||
        {
 | 
			
		||||
            if (exp == null) return this.Where(null);
 | 
			
		||||
            for (var a = 0; a < exp.Parameters.Count; a++) _tables[a].Parameter = exp.Parameters[a];
 | 
			
		||||
            return this.Where(_commonExpression.ExpressionWhereLambda(_tables, exp?.Body, null));
 | 
			
		||||
            return this.Where(_commonExpression.ExpressionWhereLambda(_tables, exp?.Body, null, _whereCascadeExpression));
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        ISelect<T1, T2, T3, T4, T5, T6, T7, T8, T9> ISelect<T1, T2, T3, T4, T5, T6, T7, T8, T9>.WhereIf(bool condition, Expression<Func<T1, T2, T3, T4, T5, T6, T7, T8, T9, bool>> exp)
 | 
			
		||||
        {
 | 
			
		||||
            if (condition == false || exp == null) return this;
 | 
			
		||||
            for (var a = 0; a < exp.Parameters.Count; a++) _tables[a].Parameter = exp.Parameters[a];
 | 
			
		||||
            return this.Where(_commonExpression.ExpressionWhereLambda(_tables, exp?.Body, null));
 | 
			
		||||
            return this.Where(_commonExpression.ExpressionWhereLambda(_tables, exp?.Body, null, _whereCascadeExpression));
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        bool ISelect<T1, T2, T3, T4, T5, T6, T7, T8, T9>.Any(Expression<Func<T1, T2, T3, T4, T5, T6, T7, T8, T9, bool>> exp)
 | 
			
		||||
        {
 | 
			
		||||
            if (exp == null) return this.Any();
 | 
			
		||||
            for (var a = 0; a < exp.Parameters.Count; a++) _tables[a].Parameter = exp.Parameters[a];
 | 
			
		||||
            return this.Where(_commonExpression.ExpressionWhereLambda(_tables, exp?.Body, null)).Any();
 | 
			
		||||
            return this.Where(_commonExpression.ExpressionWhereLambda(_tables, exp?.Body, null, _whereCascadeExpression)).Any();
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        Task<bool> ISelect<T1, T2, T3, T4, T5, T6, T7, T8, T9>.AnyAsync(Expression<Func<T1, T2, T3, T4, T5, T6, T7, T8, T9, bool>> exp)
 | 
			
		||||
        {
 | 
			
		||||
            if (exp == null) return this.AnyAsync();
 | 
			
		||||
            for (var a = 0; a < exp.Parameters.Count; a++) _tables[a].Parameter = exp.Parameters[a];
 | 
			
		||||
            return this.Where(_commonExpression.ExpressionWhereLambda(_tables, exp?.Body, null)).AnyAsync();
 | 
			
		||||
            return this.Where(_commonExpression.ExpressionWhereLambda(_tables, exp?.Body, null, _whereCascadeExpression)).AnyAsync();
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
@@ -84,7 +84,7 @@ namespace FreeSql.Internal.CommonProvider
 | 
			
		||||
 | 
			
		||||
        public ISelectGrouping<TKey, TValue> Having(Expression<Func<ISelectGroupingAggregate<TKey, TValue>, bool>> exp)
 | 
			
		||||
        {
 | 
			
		||||
            var sql = _comonExp.ExpressionWhereLambda(null, exp, getSelectGroupingMapString);
 | 
			
		||||
            var sql = _comonExp.ExpressionWhereLambda(null, exp, getSelectGroupingMapString, null);
 | 
			
		||||
            var method = _select.GetType().GetMethod("Having", new[] { typeof(string), typeof(object) });
 | 
			
		||||
            method.Invoke(_select, new object[] { sql, null });
 | 
			
		||||
            return this;
 | 
			
		||||
@@ -92,7 +92,7 @@ namespace FreeSql.Internal.CommonProvider
 | 
			
		||||
 | 
			
		||||
        public ISelectGrouping<TKey, TValue> OrderBy<TMember>(Expression<Func<ISelectGroupingAggregate<TKey, TValue>, TMember>> column)
 | 
			
		||||
        {
 | 
			
		||||
            var sql = _comonExp.ExpressionWhereLambda(null, column, getSelectGroupingMapString);
 | 
			
		||||
            var sql = _comonExp.ExpressionWhereLambda(null, column, getSelectGroupingMapString, null);
 | 
			
		||||
            var method = _select.GetType().GetMethod("OrderBy", new[] { typeof(string), typeof(object) });
 | 
			
		||||
            method.Invoke(_select, new object[] { sql, null });
 | 
			
		||||
            return this;
 | 
			
		||||
@@ -100,7 +100,7 @@ namespace FreeSql.Internal.CommonProvider
 | 
			
		||||
 | 
			
		||||
        public ISelectGrouping<TKey, TValue> OrderByDescending<TMember>(Expression<Func<ISelectGroupingAggregate<TKey, TValue>, TMember>> column)
 | 
			
		||||
        {
 | 
			
		||||
            var sql = _comonExp.ExpressionWhereLambda(null, column, getSelectGroupingMapString);
 | 
			
		||||
            var sql = _comonExp.ExpressionWhereLambda(null, column, getSelectGroupingMapString, null);
 | 
			
		||||
            var method = _select.GetType().GetMethod("OrderBy", new[] { typeof(string), typeof(object) });
 | 
			
		||||
            method.Invoke(_select, new object[] { $"{sql} DESC", null });
 | 
			
		||||
            return this;
 | 
			
		||||
@@ -112,7 +112,7 @@ namespace FreeSql.Internal.CommonProvider
 | 
			
		||||
            var field = new StringBuilder();
 | 
			
		||||
            var index = 0;
 | 
			
		||||
 | 
			
		||||
            _comonExp.ReadAnonymousField(null, field, map, ref index, select, getSelectGroupingMapString);
 | 
			
		||||
            _comonExp.ReadAnonymousField(null, field, map, ref index, select, getSelectGroupingMapString, null);
 | 
			
		||||
            var method = _select.GetType().GetMethod("ToListMapReader", BindingFlags.Instance | BindingFlags.NonPublic);
 | 
			
		||||
            method = method.MakeGenericMethod(typeof(TReturn));
 | 
			
		||||
            return method.Invoke(_select, new object[] { (map, field.Length > 0 ? field.Remove(0, 2).ToString() : null) }) as List<TReturn>;
 | 
			
		||||
@@ -123,7 +123,7 @@ namespace FreeSql.Internal.CommonProvider
 | 
			
		||||
            var field = new StringBuilder();
 | 
			
		||||
            var index = 0;
 | 
			
		||||
 | 
			
		||||
            _comonExp.ReadAnonymousField(null, field, map, ref index, select, getSelectGroupingMapString);
 | 
			
		||||
            _comonExp.ReadAnonymousField(null, field, map, ref index, select, getSelectGroupingMapString, null);
 | 
			
		||||
            var method = _select.GetType().GetMethod("ToListMapReaderAsync", BindingFlags.Instance | BindingFlags.NonPublic);
 | 
			
		||||
            method = method.MakeGenericMethod(typeof(TReturn));
 | 
			
		||||
            return method.Invoke(_select, new object[] { (map, field.Length > 0 ? field.Remove(0, 2).ToString() : null) }) as Task<List<TReturn>>;
 | 
			
		||||
@@ -136,7 +136,7 @@ namespace FreeSql.Internal.CommonProvider
 | 
			
		||||
            var field = new StringBuilder();
 | 
			
		||||
            var index = 0;
 | 
			
		||||
 | 
			
		||||
            _comonExp.ReadAnonymousField(null, field, map, ref index, select, getSelectGroupingMapString);
 | 
			
		||||
            _comonExp.ReadAnonymousField(null, field, map, ref index, select, getSelectGroupingMapString, null);
 | 
			
		||||
            var method = _select.GetType().GetMethod("ToSql", new[] { typeof(string) });
 | 
			
		||||
            return method.Invoke(_select, new object[] { field.Length > 0 ? field.Remove(0, 2).ToString() : null }) as string;
 | 
			
		||||
        }
 | 
			
		||||
 
 | 
			
		||||
@@ -21,6 +21,8 @@ namespace FreeSql.Internal.Model
 | 
			
		||||
        public string NavigateCondition { get; set; }
 | 
			
		||||
        public ParameterExpression Parameter { get; set; }
 | 
			
		||||
        public SelectTableInfoType Type { get; set; }
 | 
			
		||||
 | 
			
		||||
        public string Cascade { get; set; }
 | 
			
		||||
    }
 | 
			
		||||
    public enum SelectTableInfoType { From, LeftJoin, InnerJoin, RightJoin, Parent }
 | 
			
		||||
}
 | 
			
		||||
 
 | 
			
		||||
@@ -41,6 +41,13 @@ namespace FreeSql.Internal
 | 
			
		||||
            if (typeof(IEnumerable).IsAssignableFrom(entity) && entity.IsGenericParameter == true) return null;
 | 
			
		||||
            if (entity.IsArray) return null;
 | 
			
		||||
 | 
			
		||||
            object entityDefault = null;
 | 
			
		||||
            try
 | 
			
		||||
            {
 | 
			
		||||
                if (entity.IsAbstract == false && entity.IsInterface == false)
 | 
			
		||||
                    entityDefault = Activator.CreateInstance(entity);
 | 
			
		||||
            }
 | 
			
		||||
            catch { }
 | 
			
		||||
            var tbattr = common.GetEntityTableAttribute(entity);
 | 
			
		||||
            trytb = new TableInfo();
 | 
			
		||||
            trytb.Type = entity;
 | 
			
		||||
@@ -148,7 +155,8 @@ namespace FreeSql.Internal
 | 
			
		||||
                    trytb.ColumnsByCsIgnore.Add(p.Name, col);
 | 
			
		||||
                    continue;
 | 
			
		||||
                }
 | 
			
		||||
                colattr.DbDefautValue = trytb.Properties[p.Name].GetValue(Activator.CreateInstance(trytb.Type));
 | 
			
		||||
                if (entityDefault == null) entityDefault = Activator.CreateInstance(entity);
 | 
			
		||||
                colattr.DbDefautValue = trytb.Properties[p.Name].GetValue(entityDefault);
 | 
			
		||||
                if (colattr.DbDefautValue != null && p.PropertyType != colattr.MapType) colattr.DbDefautValue = Utils.GetDataReaderValue(colattr.MapType, colattr.DbDefautValue);
 | 
			
		||||
                if (colattr.DbDefautValue == null) colattr.DbDefautValue = tp?.defaultValue;
 | 
			
		||||
                if (colattr.IsNullable == false && colattr.DbDefautValue == null)
 | 
			
		||||
 
 | 
			
		||||
		Reference in New Issue
	
	Block a user