mirror of
				https://github.com/nsnail/FreeSql.git
				synced 2025-11-04 17:20:49 +08:00 
			
		
		
		
	- 修复 MapType 属性的表达式解析 数组.Contains 得到是映射之前的值 bug;
- 修复 MapType 属性 与 IncludeMany 变异功能未映射处理的 bug;
This commit is contained in:
		@@ -1,5 +1,6 @@
 | 
			
		||||
using FreeSql;
 | 
			
		||||
using System;
 | 
			
		||||
using System.Collections;
 | 
			
		||||
using System.Collections.Concurrent;
 | 
			
		||||
using System.Collections.Generic;
 | 
			
		||||
using System.ComponentModel;
 | 
			
		||||
@@ -40,6 +41,7 @@ public static partial class FreeSqlGlobalExtensions
 | 
			
		||||
    public static bool IsNumberType(this Type that) => that == null ? false : dicIsNumberType.Value.ContainsKey(that);
 | 
			
		||||
    public static bool IsNullableType(this Type that) => that?.FullName.StartsWith("System.Nullable`1[") == true;
 | 
			
		||||
    public static bool IsAnonymousType(this Type that) => that?.FullName.StartsWith("<>f__AnonymousType") == true;
 | 
			
		||||
    public static bool IsArrayOrList(this Type that) => that == null ? false : (that.IsArray || typeof(IList).IsAssignableFrom(that));
 | 
			
		||||
    public static Type NullableTypeOrThis(this Type that) => that?.IsNullableType() == true ? that.GetGenericArguments().First() : that;
 | 
			
		||||
    internal static string NotNullAndConcat(this string that, params object[] args) => string.IsNullOrEmpty(that) ? null : string.Concat(new object[] { that }.Concat(args));
 | 
			
		||||
 | 
			
		||||
 
 | 
			
		||||
@@ -1996,6 +1996,137 @@
 | 
			
		||||
            <param name="parms"></param>
 | 
			
		||||
            <returns></returns>
 | 
			
		||||
        </member>
 | 
			
		||||
        <member name="M:FreeSql.IAdo.ExecuteReaderAsync(System.Func{System.Data.Common.DbDataReader,System.Threading.Tasks.Task},System.Data.CommandType,System.String,System.Data.Common.DbParameter[])">
 | 
			
		||||
            <summary>
 | 
			
		||||
            查询,若使用读写分离,查询【从库】条件cmdText.StartsWith("SELECT "),否则查询【主库】
 | 
			
		||||
            </summary>
 | 
			
		||||
            <param name="readerHander"></param>
 | 
			
		||||
            <param name="cmdType"></param>
 | 
			
		||||
            <param name="cmdText"></param>
 | 
			
		||||
            <param name="cmdParms"></param>
 | 
			
		||||
        </member>
 | 
			
		||||
        <member name="M:FreeSql.IAdo.ExecuteReaderAsync(System.Func{System.Data.Common.DbDataReader,System.Threading.Tasks.Task},System.String,System.Object)">
 | 
			
		||||
            <summary>
 | 
			
		||||
            查询,ExecuteReaderAsync(dr => {}, "select * from user where age > @age", new { age = 25 })
 | 
			
		||||
            </summary>
 | 
			
		||||
            <param name="cmdText"></param>
 | 
			
		||||
            <param name="parms"></param>
 | 
			
		||||
        </member>
 | 
			
		||||
        <member name="M:FreeSql.IAdo.ExecuteArrayAsync(System.Data.CommandType,System.String,System.Data.Common.DbParameter[])">
 | 
			
		||||
            <summary>
 | 
			
		||||
            查询
 | 
			
		||||
            </summary>
 | 
			
		||||
            <param name="cmdText"></param>
 | 
			
		||||
            <param name="cmdParms"></param>
 | 
			
		||||
        </member>
 | 
			
		||||
        <member name="M:FreeSql.IAdo.ExecuteArrayAsync(System.String,System.Object)">
 | 
			
		||||
            <summary>
 | 
			
		||||
            查询,ExecuteArrayAsync("select * from user where age > @age", new { age = 25 })
 | 
			
		||||
            </summary>
 | 
			
		||||
            <param name="cmdText"></param>
 | 
			
		||||
            <param name="parms"></param>
 | 
			
		||||
            <returns></returns>
 | 
			
		||||
        </member>
 | 
			
		||||
        <member name="M:FreeSql.IAdo.ExecuteDataSetAsync(System.Data.CommandType,System.String,System.Data.Common.DbParameter[])">
 | 
			
		||||
            <summary>
 | 
			
		||||
            查询
 | 
			
		||||
            </summary>
 | 
			
		||||
            <param name="cmdText"></param>
 | 
			
		||||
            <param name="cmdParms"></param>
 | 
			
		||||
        </member>
 | 
			
		||||
        <member name="M:FreeSql.IAdo.ExecuteDataSetAsync(System.String,System.Object)">
 | 
			
		||||
            <summary>
 | 
			
		||||
            查询,ExecuteDataSetAsync("select * from user where age > @age; select 2", new { age = 25 })
 | 
			
		||||
            </summary>
 | 
			
		||||
            <param name="cmdText"></param>
 | 
			
		||||
            <param name="parms"></param>
 | 
			
		||||
            <returns></returns>
 | 
			
		||||
        </member>
 | 
			
		||||
        <member name="M:FreeSql.IAdo.ExecuteDataTableAsync(System.Data.CommandType,System.String,System.Data.Common.DbParameter[])">
 | 
			
		||||
            <summary>
 | 
			
		||||
            查询
 | 
			
		||||
            </summary>
 | 
			
		||||
            <param name="cmdText"></param>
 | 
			
		||||
            <param name="cmdParms"></param>
 | 
			
		||||
        </member>
 | 
			
		||||
        <member name="M:FreeSql.IAdo.ExecuteDataTableAsync(System.String,System.Object)">
 | 
			
		||||
            <summary>
 | 
			
		||||
            查询,ExecuteDataTableAsync("select * from user where age > @age", new { age = 25 })
 | 
			
		||||
            </summary>
 | 
			
		||||
            <param name="cmdText"></param>
 | 
			
		||||
            <param name="parms"></param>
 | 
			
		||||
            <returns></returns>
 | 
			
		||||
        </member>
 | 
			
		||||
        <member name="M:FreeSql.IAdo.ExecuteNonQueryAsync(System.Data.CommandType,System.String,System.Data.Common.DbParameter[])">
 | 
			
		||||
            <summary>
 | 
			
		||||
            在【主库】执行
 | 
			
		||||
            </summary>
 | 
			
		||||
            <param name="cmdType"></param>
 | 
			
		||||
            <param name="cmdText"></param>
 | 
			
		||||
            <param name="cmdParms"></param>
 | 
			
		||||
        </member>
 | 
			
		||||
        <member name="M:FreeSql.IAdo.ExecuteNonQueryAsync(System.String,System.Object)">
 | 
			
		||||
            <summary>
 | 
			
		||||
            在【主库】执行,ExecuteNonQueryAsync("delete from user where age > @age", new { age = 25 })
 | 
			
		||||
            </summary>
 | 
			
		||||
            <param name="cmdText"></param>
 | 
			
		||||
            <param name="parms"></param>
 | 
			
		||||
            <returns></returns>
 | 
			
		||||
        </member>
 | 
			
		||||
        <member name="M:FreeSql.IAdo.ExecuteScalarAsync(System.Data.CommandType,System.String,System.Data.Common.DbParameter[])">
 | 
			
		||||
            <summary>
 | 
			
		||||
            在【主库】执行
 | 
			
		||||
            </summary>
 | 
			
		||||
            <param name="cmdType"></param>
 | 
			
		||||
            <param name="cmdText"></param>
 | 
			
		||||
            <param name="cmdParms"></param>
 | 
			
		||||
        </member>
 | 
			
		||||
        <member name="M:FreeSql.IAdo.ExecuteScalarAsync(System.String,System.Object)">
 | 
			
		||||
            <summary>
 | 
			
		||||
            在【主库】执行,ExecuteScalarAsync("select 1 from user where age > @age", new { age = 25 })
 | 
			
		||||
            </summary>
 | 
			
		||||
            <param name="cmdText"></param>
 | 
			
		||||
            <param name="parms"></param>
 | 
			
		||||
            <returns></returns>
 | 
			
		||||
        </member>
 | 
			
		||||
        <member name="M:FreeSql.IAdo.QueryAsync``1(System.Data.CommandType,System.String,System.Data.Common.DbParameter[])">
 | 
			
		||||
            <summary>
 | 
			
		||||
            执行SQL返回对象集合,QueryAsync<User>("select * from user where age > @age", new SqlParameter { ParameterName = "age", Value = 25 })
 | 
			
		||||
            </summary>
 | 
			
		||||
            <typeparam name="T"></typeparam>
 | 
			
		||||
            <param name="cmdType"></param>
 | 
			
		||||
            <param name="cmdText"></param>
 | 
			
		||||
            <param name="cmdParms"></param>
 | 
			
		||||
            <returns></returns>
 | 
			
		||||
        </member>
 | 
			
		||||
        <member name="M:FreeSql.IAdo.QueryAsync``1(System.String,System.Object)">
 | 
			
		||||
            <summary>
 | 
			
		||||
            执行SQL返回对象集合,QueryAsync<User>("select * from user where age > @age", new { age = 25 })
 | 
			
		||||
            </summary>
 | 
			
		||||
            <typeparam name="T"></typeparam>
 | 
			
		||||
            <param name="cmdText"></param>
 | 
			
		||||
            <param name="parms"></param>
 | 
			
		||||
            <returns></returns>
 | 
			
		||||
        </member>
 | 
			
		||||
        <member name="M:FreeSql.IAdo.QueryAsync``2(System.Data.CommandType,System.String,System.Data.Common.DbParameter[])">
 | 
			
		||||
            <summary>
 | 
			
		||||
            执行SQL返回对象集合,Query<User>("select * from user where age > @age; select * from address", new SqlParameter { ParameterName = "age", Value = 25 })
 | 
			
		||||
            </summary>
 | 
			
		||||
            <typeparam name="T1"></typeparam>
 | 
			
		||||
            <param name="cmdType"></param>
 | 
			
		||||
            <param name="cmdText"></param>
 | 
			
		||||
            <param name="cmdParms"></param>
 | 
			
		||||
            <returns></returns>
 | 
			
		||||
        </member>
 | 
			
		||||
        <member name="M:FreeSql.IAdo.QueryAsync``2(System.String,System.Object)">
 | 
			
		||||
            <summary>
 | 
			
		||||
            执行SQL返回对象集合,Query<User>("select * from user where age > @age; select * from address", new { age = 25 })
 | 
			
		||||
            </summary>
 | 
			
		||||
            <typeparam name="T1"></typeparam>
 | 
			
		||||
            <param name="cmdText"></param>
 | 
			
		||||
            <param name="parms"></param>
 | 
			
		||||
            <returns></returns>
 | 
			
		||||
        </member>
 | 
			
		||||
        <member name="P:FreeSql.IAop.ParseExpression">
 | 
			
		||||
            <summary>
 | 
			
		||||
            可自定义解析表达式
 | 
			
		||||
 
 | 
			
		||||
@@ -932,12 +932,12 @@ namespace FreeSql.Internal
 | 
			
		||||
                                throw new ArgumentException($"{tb.DbName}.{memberExp.Member.Name} 被忽略,请检查 IsIgnore 设置,确认 get/set 为 public");
 | 
			
		||||
                            throw new ArgumentException($"{tb.DbName} 找不到列 {memberExp.Member.Name}");
 | 
			
		||||
                        }
 | 
			
		||||
                        var curcol = tb.ColumnsByCs[memberExp.Member.Name];
 | 
			
		||||
                        if (tsc._selectColumnMap != null)
 | 
			
		||||
                        {
 | 
			
		||||
                            tsc._selectColumnMap.Add(new SelectColumnInfo { Table = null, Column = tb.ColumnsByCs[memberExp.Member.Name] });
 | 
			
		||||
                        }
 | 
			
		||||
                        var name = tb.ColumnsByCs[memberExp.Member.Name].Attribute.Name;
 | 
			
		||||
                            tsc._selectColumnMap.Add(new SelectColumnInfo { Table = null, Column = curcol });
 | 
			
		||||
                        var name = curcol.Attribute.Name;
 | 
			
		||||
                        if (tsc.isQuoteName) name = _common.QuoteSqlName(name);
 | 
			
		||||
                        tsc.mapTypeTmp = curcol.Attribute.MapType == curcol.CsType ? null : curcol.Attribute.MapType;
 | 
			
		||||
                        if (string.IsNullOrEmpty(tsc.alias001)) return name;
 | 
			
		||||
                        return $"{tsc.alias001}.{name}";
 | 
			
		||||
                    }
 | 
			
		||||
@@ -1098,7 +1098,8 @@ namespace FreeSql.Internal
 | 
			
		||||
                                    tsc._selectColumnMap.Add(new SelectColumnInfo { Table = find2, Column = col2 });
 | 
			
		||||
                                    return "";
 | 
			
		||||
                                }
 | 
			
		||||
                                name2 = tb2.ColumnsByCs[mp2.Member.Name].Attribute.Name;
 | 
			
		||||
                                name2 = col2.Attribute.Name;
 | 
			
		||||
                                tsc.mapTypeTmp = col2.Attribute.MapType == col2.CsType ? null : col2.Attribute.MapType;
 | 
			
		||||
                                break;
 | 
			
		||||
                            case ExpressionType.Call: break;
 | 
			
		||||
                        }
 | 
			
		||||
@@ -1150,10 +1151,22 @@ namespace FreeSql.Internal
 | 
			
		||||
            public bool isDisableDiyParse { get; set; }
 | 
			
		||||
            public ExpressionStyle style { get; set; }
 | 
			
		||||
            public Type mapType { get; set; }
 | 
			
		||||
            public Type mapTypeTmp { get; set; }
 | 
			
		||||
            public TableInfo currentTable { get; set; }
 | 
			
		||||
            public List<LambdaExpression> whereCascadeExpression { get; set; }
 | 
			
		||||
            public string alias001 { get; set; } //单表字段的表别名
 | 
			
		||||
 | 
			
		||||
            public void SetMapTypeTmp(Type newValue)
 | 
			
		||||
            {
 | 
			
		||||
                this.mapTypeTmp = null;
 | 
			
		||||
            }
 | 
			
		||||
            public Type SetMapTypeReturnOld(Type newValue)
 | 
			
		||||
            {
 | 
			
		||||
                var old = this.mapType;
 | 
			
		||||
                this.mapType = newValue;
 | 
			
		||||
                return old;
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
            public ExpTSC CloneSetgetSelectGroupingMapStringAndgetSelectGroupingMapStringAndtbtype(List<SelectColumnInfo> v1, Func<Expression[], string> v2, SelectTableInfoType v3)
 | 
			
		||||
            {
 | 
			
		||||
                return new ExpTSC
 | 
			
		||||
 
 | 
			
		||||
@@ -605,7 +605,7 @@ namespace FreeSql.Internal.CommonProvider
 | 
			
		||||
                                    for (var z = 0; z < tbref.Columns.Count; z++)
 | 
			
		||||
                                    {
 | 
			
		||||
                                        if (z > 0) sbWhereOne.Append(" AND ");
 | 
			
		||||
                                        sbWhereOne.Append(_commonUtils.FormatSql($"{subSelectT1Alias}.{_commonUtils.QuoteSqlName(tbref.RefColumns[z].Attribute.Name)}={{0}}", getListValue(list[y], tbref.Columns[z].CsName, z)));
 | 
			
		||||
                                        sbWhereOne.Append(_commonUtils.FormatSql($"{subSelectT1Alias}.{_commonUtils.QuoteSqlName(tbref.RefColumns[z].Attribute.Name)}={{0}}", Utils.GetDataReaderValue(tbref.RefColumns[z].Attribute.MapType, getListValue(list[y], tbref.Columns[z].CsName, z))));
 | 
			
		||||
                                    }
 | 
			
		||||
                                    sbWhereOne.Append(")");
 | 
			
		||||
                                    var whereOne = sbWhereOne.ToString();
 | 
			
		||||
@@ -797,7 +797,7 @@ namespace FreeSql.Internal.CommonProvider
 | 
			
		||||
                                    for (var z = 0; z < tbref.Columns.Count; z++)
 | 
			
		||||
                                    {
 | 
			
		||||
                                        if (z > 0) sbWhereOne.Append(" AND ");
 | 
			
		||||
                                        sbWhereOne.Append(_commonUtils.FormatSql($" midtb.{_commonUtils.QuoteSqlName(tbref.MiddleColumns[z].Attribute.Name)}={{0}}", getListValue1(list[y], tbref.Columns[z].CsName)));
 | 
			
		||||
                                        sbWhereOne.Append(_commonUtils.FormatSql($" midtb.{_commonUtils.QuoteSqlName(tbref.MiddleColumns[z].Attribute.Name)}={{0}}", Utils.GetDataReaderValue(tbref.MiddleColumns[z].Attribute.MapType, getListValue1(list[y], tbref.Columns[z].CsName))));
 | 
			
		||||
                                    }
 | 
			
		||||
                                    sbWhereOne.Append(")");
 | 
			
		||||
                                    var whereOne = sbWhereOne.ToString();
 | 
			
		||||
@@ -825,7 +825,7 @@ namespace FreeSql.Internal.CommonProvider
 | 
			
		||||
                                subSelect._where.Clear();
 | 
			
		||||
                                if (tbref.Columns.Count == 1)
 | 
			
		||||
                                {
 | 
			
		||||
                                    subSelect.Where(_commonUtils.FormatSql($"midtb.{_commonUtils.QuoteSqlName(tbref.MiddleColumns[0].Attribute.Name)} in {{0}}", list.Select(a => getListValue1(a, tbref.Columns[0].CsName)).Distinct()));
 | 
			
		||||
                                    subSelect.Where(_commonUtils.FormatSql($"midtb.{_commonUtils.QuoteSqlName(tbref.MiddleColumns[0].Attribute.Name)} in {{0}}", list.Select(a => Utils.GetDataReaderValue(tbref.MiddleColumns[0].Attribute.MapType, getListValue1(a, tbref.Columns[0].CsName))).Distinct()));
 | 
			
		||||
                                }
 | 
			
		||||
                                else
 | 
			
		||||
                                {
 | 
			
		||||
 
 | 
			
		||||
@@ -31,7 +31,7 @@ namespace FreeSql.MySql
 | 
			
		||||
        public override object AddslashesProcessParam(object param, Type mapType)
 | 
			
		||||
        {
 | 
			
		||||
            if (param == null) return "NULL";
 | 
			
		||||
            if (mapType != null && mapType != param.GetType())
 | 
			
		||||
            if (mapType != null && mapType != param.GetType() && (param is IEnumerable == false || mapType.IsArrayOrList()))
 | 
			
		||||
                param = Utils.GetDataReaderValue(mapType, param);
 | 
			
		||||
            if (param is bool || param is bool?)
 | 
			
		||||
                return (bool)param ? 1 : 0;
 | 
			
		||||
 
 | 
			
		||||
@@ -99,14 +99,18 @@ namespace FreeSql.MySql
 | 
			
		||||
                        argIndex++;
 | 
			
		||||
                    }
 | 
			
		||||
                    if (objType == null) objType = callExp.Method.DeclaringType;
 | 
			
		||||
                    if (objType != null || objType.IsArray || typeof(IList).IsAssignableFrom(callExp.Method.DeclaringType))
 | 
			
		||||
                    if (objType != null || objType.IsArrayOrList())
 | 
			
		||||
                    {
 | 
			
		||||
                        tsc?.SetMapTypeTmp(null);
 | 
			
		||||
                        var args1 = getExp(callExp.Arguments[argIndex]);
 | 
			
		||||
                        var oldMapType = tsc?.SetMapTypeReturnOld(tsc?.mapTypeTmp);
 | 
			
		||||
                        var left = objExp == null ? null : getExp(objExp);
 | 
			
		||||
                        tsc.SetMapTypeReturnOld(oldMapType);
 | 
			
		||||
                        switch (callExp.Method.Name)
 | 
			
		||||
                        {
 | 
			
		||||
                            case "Contains":
 | 
			
		||||
                                //判断 in
 | 
			
		||||
                                return $"({getExp(callExp.Arguments[argIndex])}) in {left}";
 | 
			
		||||
                                return $"({args1}) in {left}";
 | 
			
		||||
                        }
 | 
			
		||||
                    }
 | 
			
		||||
                    break;
 | 
			
		||||
 
 | 
			
		||||
@@ -32,7 +32,7 @@ namespace FreeSql.Odbc.Default
 | 
			
		||||
        public override object AddslashesProcessParam(object param, Type mapType)
 | 
			
		||||
        {
 | 
			
		||||
            if (param == null) return "NULL";
 | 
			
		||||
            if (mapType != null && mapType != param.GetType())
 | 
			
		||||
            if (mapType != null && mapType != param.GetType() && (param is IEnumerable == false || mapType.IsArrayOrList()))
 | 
			
		||||
                param = Utils.GetDataReaderValue(mapType, param);
 | 
			
		||||
            if (param is bool || param is bool?)
 | 
			
		||||
                return (bool)param ? 1 : 0;
 | 
			
		||||
 
 | 
			
		||||
@@ -106,14 +106,18 @@ namespace FreeSql.Odbc.Default
 | 
			
		||||
                        argIndex++;
 | 
			
		||||
                    }
 | 
			
		||||
                    if (objType == null) objType = callExp.Method.DeclaringType;
 | 
			
		||||
                    if (objType != null || objType.IsArray || typeof(IList).IsAssignableFrom(callExp.Method.DeclaringType))
 | 
			
		||||
                    if (objType != null || objType.IsArrayOrList())
 | 
			
		||||
                    {
 | 
			
		||||
                        tsc?.SetMapTypeTmp(null);
 | 
			
		||||
                        var args1 = getExp(callExp.Arguments[argIndex]);
 | 
			
		||||
                        var oldMapType = tsc?.SetMapTypeReturnOld(tsc?.mapTypeTmp);
 | 
			
		||||
                        var left = objExp == null ? null : getExp(objExp);
 | 
			
		||||
                        tsc.SetMapTypeReturnOld(oldMapType);
 | 
			
		||||
                        switch (callExp.Method.Name)
 | 
			
		||||
                        {
 | 
			
		||||
                            case "Contains":
 | 
			
		||||
                                //判断 in
 | 
			
		||||
                                return $"({getExp(callExp.Arguments[argIndex])}) in {left}";
 | 
			
		||||
                                return $"({args1}) in {left}";
 | 
			
		||||
                        }
 | 
			
		||||
                    }
 | 
			
		||||
                    break;
 | 
			
		||||
 
 | 
			
		||||
@@ -31,7 +31,7 @@ namespace FreeSql.Odbc.MySql
 | 
			
		||||
        public override object AddslashesProcessParam(object param, Type mapType)
 | 
			
		||||
        {
 | 
			
		||||
            if (param == null) return "NULL";
 | 
			
		||||
            if (mapType != null && mapType != param.GetType())
 | 
			
		||||
            if (mapType != null && mapType != param.GetType() && (param is IEnumerable == false || mapType.IsArrayOrList()))
 | 
			
		||||
                param = Utils.GetDataReaderValue(mapType, param);
 | 
			
		||||
            if (param is bool || param is bool?)
 | 
			
		||||
                return (bool)param ? 1 : 0;
 | 
			
		||||
 
 | 
			
		||||
@@ -99,14 +99,18 @@ namespace FreeSql.Odbc.MySql
 | 
			
		||||
                        argIndex++;
 | 
			
		||||
                    }
 | 
			
		||||
                    if (objType == null) objType = callExp.Method.DeclaringType;
 | 
			
		||||
                    if (objType != null || objType.IsArray || typeof(IList).IsAssignableFrom(callExp.Method.DeclaringType))
 | 
			
		||||
                    if (objType != null || objType.IsArrayOrList())
 | 
			
		||||
                    {
 | 
			
		||||
                        tsc?.SetMapTypeTmp(null);
 | 
			
		||||
                        var args1 = getExp(callExp.Arguments[argIndex]);
 | 
			
		||||
                        var oldMapType = tsc?.SetMapTypeReturnOld(tsc?.mapTypeTmp);
 | 
			
		||||
                        var left = objExp == null ? null : getExp(objExp);
 | 
			
		||||
                        tsc.SetMapTypeReturnOld(oldMapType);
 | 
			
		||||
                        switch (callExp.Method.Name)
 | 
			
		||||
                        {
 | 
			
		||||
                            case "Contains":
 | 
			
		||||
                                //判断 in
 | 
			
		||||
                                return $"({getExp(callExp.Arguments[argIndex])}) in {left}";
 | 
			
		||||
                                return $"({args1}) in {left}";
 | 
			
		||||
                        }
 | 
			
		||||
                    }
 | 
			
		||||
                    break;
 | 
			
		||||
 
 | 
			
		||||
@@ -30,7 +30,7 @@ namespace FreeSql.Odbc.Oracle
 | 
			
		||||
        public override object AddslashesProcessParam(object param, Type mapType)
 | 
			
		||||
        {
 | 
			
		||||
            if (param == null) return "NULL";
 | 
			
		||||
            if (mapType != null && mapType != param.GetType())
 | 
			
		||||
            if (mapType != null && mapType != param.GetType() && (param is IEnumerable == false || mapType.IsArrayOrList()))
 | 
			
		||||
                param = Utils.GetDataReaderValue(mapType, param);
 | 
			
		||||
            if (param is bool || param is bool?)
 | 
			
		||||
                return (bool)param ? 1 : 0;
 | 
			
		||||
 
 | 
			
		||||
@@ -99,14 +99,18 @@ namespace FreeSql.Odbc.Oracle
 | 
			
		||||
                        argIndex++;
 | 
			
		||||
                    }
 | 
			
		||||
                    if (objType == null) objType = callExp.Method.DeclaringType;
 | 
			
		||||
                    if (objType != null || objType.IsArray || typeof(IList).IsAssignableFrom(callExp.Method.DeclaringType))
 | 
			
		||||
                    if (objType != null || objType.IsArrayOrList())
 | 
			
		||||
                    {
 | 
			
		||||
                        tsc?.SetMapTypeTmp(null);
 | 
			
		||||
                        var args1 = getExp(callExp.Arguments[argIndex]);
 | 
			
		||||
                        var oldMapType = tsc?.SetMapTypeReturnOld(tsc?.mapTypeTmp);
 | 
			
		||||
                        var left = objExp == null ? null : getExp(objExp);
 | 
			
		||||
                        tsc.SetMapTypeReturnOld(oldMapType);
 | 
			
		||||
                        switch (callExp.Method.Name)
 | 
			
		||||
                        {
 | 
			
		||||
                            case "Contains":
 | 
			
		||||
                                //判断 in
 | 
			
		||||
                                return $"({getExp(callExp.Arguments[argIndex])}) in {left}";
 | 
			
		||||
                                return $"({args1}) in {left}";
 | 
			
		||||
                        }
 | 
			
		||||
                    }
 | 
			
		||||
                    break;
 | 
			
		||||
 
 | 
			
		||||
@@ -32,7 +32,7 @@ namespace FreeSql.Odbc.PostgreSQL
 | 
			
		||||
        public override object AddslashesProcessParam(object param, Type mapType)
 | 
			
		||||
        {
 | 
			
		||||
            if (param == null) return "NULL";
 | 
			
		||||
            if (mapType != null && mapType != param.GetType())
 | 
			
		||||
            if (mapType != null && mapType != param.GetType() && (param is IEnumerable == false || mapType.IsArrayOrList()))
 | 
			
		||||
                param = Utils.GetDataReaderValue(mapType, param);
 | 
			
		||||
            if (param is bool || param is bool?)
 | 
			
		||||
                return (bool)param ? "'t'" : "'f'";
 | 
			
		||||
 
 | 
			
		||||
@@ -103,11 +103,12 @@ namespace FreeSql.Odbc.PostgreSQL
 | 
			
		||||
                        argIndex++;
 | 
			
		||||
                    }
 | 
			
		||||
                    if (objType == null) objType = callExp.Method.DeclaringType;
 | 
			
		||||
                    if (objType != null || objType.IsArray || typeof(IList).IsAssignableFrom(callExp.Method.DeclaringType))
 | 
			
		||||
                    if (objType != null || objType.IsArrayOrList())
 | 
			
		||||
                    {
 | 
			
		||||
                        var left = objExp == null ? null : getExp(objExp);
 | 
			
		||||
                        string left = null;
 | 
			
		||||
                        if (objType.FullName == typeof(Dictionary<string, string>).FullName)
 | 
			
		||||
                        {
 | 
			
		||||
                            left = objExp == null ? null : getExp(objExp);
 | 
			
		||||
                            switch (callExp.Method.Name)
 | 
			
		||||
                            {
 | 
			
		||||
                                case "Contains":
 | 
			
		||||
@@ -125,24 +126,30 @@ namespace FreeSql.Odbc.PostgreSQL
 | 
			
		||||
                        switch (callExp.Method.Name)
 | 
			
		||||
                        {
 | 
			
		||||
                            case "Any":
 | 
			
		||||
                                left = objExp == null ? null : getExp(objExp);
 | 
			
		||||
                                if (left.StartsWith("(") || left.EndsWith(")")) left = $"array[{left.TrimStart('(').TrimEnd(')')}]";
 | 
			
		||||
                                return $"(case when {left} is null then 0 else array_length({left},1) end > 0)";
 | 
			
		||||
                            case "Contains":
 | 
			
		||||
                                tsc?.SetMapTypeTmp(null);
 | 
			
		||||
                                var args1 = getExp(callExp.Arguments[argIndex]);
 | 
			
		||||
                                var oldMapType = tsc?.SetMapTypeReturnOld(tsc?.mapTypeTmp);
 | 
			
		||||
                                left = objExp == null ? null : getExp(objExp);
 | 
			
		||||
                                tsc.SetMapTypeReturnOld(oldMapType);
 | 
			
		||||
                                //判断 in 或 array @> array
 | 
			
		||||
                                var right1 = getExp(callExp.Arguments[argIndex]);
 | 
			
		||||
                                if (left.StartsWith("array[") || left.EndsWith("]"))
 | 
			
		||||
                                    return $"{right1} in ({left.Substring(6, left.Length - 7)})";
 | 
			
		||||
                                    return $"{args1} in ({left.Substring(6, left.Length - 7)})";
 | 
			
		||||
                                if (left.StartsWith("(") || left.EndsWith(")"))
 | 
			
		||||
                                    return $"{right1} in {left}";
 | 
			
		||||
                                if (right1.StartsWith("(") || right1.EndsWith(")")) right1 = $"array[{right1.TrimStart('(').TrimEnd(')')}]";
 | 
			
		||||
                                right1 = $"array[{right1}]";
 | 
			
		||||
                                    return $"{args1} in {left}";
 | 
			
		||||
                                if (args1.StartsWith("(") || args1.EndsWith(")")) args1 = $"array[{args1.TrimStart('(').TrimEnd(')')}]";
 | 
			
		||||
                                args1 = $"array[{args1}]";
 | 
			
		||||
                                if (objExp != null)
 | 
			
		||||
                                {
 | 
			
		||||
                                    var dbinfo = _common._orm.CodeFirst.GetDbInfo(objExp.Type);
 | 
			
		||||
                                    if (dbinfo.HasValue) right1 = $"{right1}::{dbinfo.Value.dbtype}";
 | 
			
		||||
                                    if (dbinfo.HasValue) args1 = $"{args1}::{dbinfo.Value.dbtype}";
 | 
			
		||||
                                }
 | 
			
		||||
                                return $"({left} @> {right1})";
 | 
			
		||||
                                return $"({left} @> {args1})";
 | 
			
		||||
                            case "Concat":
 | 
			
		||||
                                left = objExp == null ? null : getExp(objExp);
 | 
			
		||||
                                if (left.StartsWith("(") || left.EndsWith(")")) left = $"array[{left.TrimStart('(').TrimEnd(')')}]";
 | 
			
		||||
                                var right2 = getExp(callExp.Arguments[argIndex]);
 | 
			
		||||
                                if (right2.StartsWith("(") || right2.EndsWith(")")) right2 = $"array[{right2.TrimStart('(').TrimEnd(')')}]";
 | 
			
		||||
@@ -151,6 +158,7 @@ namespace FreeSql.Odbc.PostgreSQL
 | 
			
		||||
                            case "GetLongLength":
 | 
			
		||||
                            case "Length":
 | 
			
		||||
                            case "Count":
 | 
			
		||||
                                left = objExp == null ? null : getExp(objExp);
 | 
			
		||||
                                if (left.StartsWith("(") || left.EndsWith(")")) left = $"array[{left.TrimStart('(').TrimEnd(')')}]";
 | 
			
		||||
                                return $"case when {left} is null then 0 else array_length({left},1) end";
 | 
			
		||||
                        }
 | 
			
		||||
 
 | 
			
		||||
@@ -30,7 +30,7 @@ namespace FreeSql.Odbc.SqlServer
 | 
			
		||||
        public override object AddslashesProcessParam(object param, Type mapType)
 | 
			
		||||
        {
 | 
			
		||||
            if (param == null) return "NULL";
 | 
			
		||||
            if (mapType != null && mapType != param.GetType())
 | 
			
		||||
            if (mapType != null && mapType != param.GetType() && (param is IEnumerable == false || mapType.IsArrayOrList()))
 | 
			
		||||
                param = Utils.GetDataReaderValue(mapType, param);
 | 
			
		||||
            if (param is bool || param is bool?)
 | 
			
		||||
                return (bool)param ? 1 : 0;
 | 
			
		||||
 
 | 
			
		||||
@@ -103,14 +103,18 @@ namespace FreeSql.Odbc.SqlServer
 | 
			
		||||
                        argIndex++;
 | 
			
		||||
                    }
 | 
			
		||||
                    if (objType == null) objType = callExp.Method.DeclaringType;
 | 
			
		||||
                    if (objType != null || objType.IsArray || typeof(IList).IsAssignableFrom(callExp.Method.DeclaringType))
 | 
			
		||||
                    if (objType != null || objType.IsArrayOrList())
 | 
			
		||||
                    {
 | 
			
		||||
                        tsc?.SetMapTypeTmp(null);
 | 
			
		||||
                        var args1 = getExp(callExp.Arguments[argIndex]);
 | 
			
		||||
                        var oldMapType = tsc?.SetMapTypeReturnOld(tsc?.mapTypeTmp);
 | 
			
		||||
                        var left = objExp == null ? null : getExp(objExp);
 | 
			
		||||
                        tsc.SetMapTypeReturnOld(oldMapType);
 | 
			
		||||
                        switch (callExp.Method.Name)
 | 
			
		||||
                        {
 | 
			
		||||
                            case "Contains":
 | 
			
		||||
                                //判断 in
 | 
			
		||||
                                return $"({getExp(callExp.Arguments[argIndex])}) in {left}";
 | 
			
		||||
                                return $"({args1}) in {left}";
 | 
			
		||||
                        }
 | 
			
		||||
                    }
 | 
			
		||||
                    break;
 | 
			
		||||
 
 | 
			
		||||
@@ -30,7 +30,7 @@ namespace FreeSql.Oracle
 | 
			
		||||
        public override object AddslashesProcessParam(object param, Type mapType)
 | 
			
		||||
        {
 | 
			
		||||
            if (param == null) return "NULL";
 | 
			
		||||
            if (mapType != null && mapType != param.GetType())
 | 
			
		||||
            if (mapType != null && mapType != param.GetType() && (param is IEnumerable == false || mapType.IsArrayOrList()))
 | 
			
		||||
                param = Utils.GetDataReaderValue(mapType, param);
 | 
			
		||||
            if (param is bool || param is bool?)
 | 
			
		||||
                return (bool)param ? 1 : 0;
 | 
			
		||||
 
 | 
			
		||||
@@ -99,14 +99,18 @@ namespace FreeSql.Oracle
 | 
			
		||||
                        argIndex++;
 | 
			
		||||
                    }
 | 
			
		||||
                    if (objType == null) objType = callExp.Method.DeclaringType;
 | 
			
		||||
                    if (objType != null || objType.IsArray || typeof(IList).IsAssignableFrom(callExp.Method.DeclaringType))
 | 
			
		||||
                    if (objType != null || objType.IsArrayOrList())
 | 
			
		||||
                    {
 | 
			
		||||
                        tsc?.SetMapTypeTmp(null);
 | 
			
		||||
                        var args1 = getExp(callExp.Arguments[argIndex]);
 | 
			
		||||
                        var oldMapType = tsc?.SetMapTypeReturnOld(tsc?.mapTypeTmp);
 | 
			
		||||
                        var left = objExp == null ? null : getExp(objExp);
 | 
			
		||||
                        tsc.SetMapTypeReturnOld(oldMapType);
 | 
			
		||||
                        switch (callExp.Method.Name)
 | 
			
		||||
                        {
 | 
			
		||||
                            case "Contains":
 | 
			
		||||
                                //判断 in
 | 
			
		||||
                                return $"({getExp(callExp.Arguments[argIndex])}) in {left}";
 | 
			
		||||
                                return $"({args1}) in {left}";
 | 
			
		||||
                        }
 | 
			
		||||
                    }
 | 
			
		||||
                    break;
 | 
			
		||||
 
 | 
			
		||||
@@ -33,9 +33,9 @@ namespace FreeSql.PostgreSQL
 | 
			
		||||
        public override object AddslashesProcessParam(object param, Type mapType)
 | 
			
		||||
        {
 | 
			
		||||
            if (param == null) return "NULL";
 | 
			
		||||
            if (mapType != null && mapType != param.GetType())
 | 
			
		||||
            if (mapType != null && mapType != param.GetType() && (param is IEnumerable == false || mapType.IsArrayOrList() || param is JToken || param is JObject || param is JArray))
 | 
			
		||||
                param = Utils.GetDataReaderValue(mapType, param);
 | 
			
		||||
            bool isdic = false;
 | 
			
		||||
            bool isdic;
 | 
			
		||||
            if (param is bool || param is bool?)
 | 
			
		||||
                return (bool)param ? "'t'" : "'f'";
 | 
			
		||||
            else if (param is string || param is char)
 | 
			
		||||
 
 | 
			
		||||
@@ -104,14 +104,15 @@ namespace FreeSql.PostgreSQL
 | 
			
		||||
                        argIndex++;
 | 
			
		||||
                    }
 | 
			
		||||
                    if (objType == null) objType = callExp.Method.DeclaringType;
 | 
			
		||||
                    if (objType != null || objType.IsArray || typeof(IList).IsAssignableFrom(callExp.Method.DeclaringType))
 | 
			
		||||
                    if (objType != null || objType.IsArrayOrList())
 | 
			
		||||
                    {
 | 
			
		||||
                        var left = objExp == null ? null : getExp(objExp);
 | 
			
		||||
                        string left = null;
 | 
			
		||||
                        switch (objType.FullName)
 | 
			
		||||
                        {
 | 
			
		||||
                            case "Newtonsoft.Json.Linq.JToken":
 | 
			
		||||
                            case "Newtonsoft.Json.Linq.JObject":
 | 
			
		||||
                            case "Newtonsoft.Json.Linq.JArray":
 | 
			
		||||
                                left = objExp == null ? null : getExp(objExp);
 | 
			
		||||
                                switch (callExp.Method.Name)
 | 
			
		||||
                                {
 | 
			
		||||
                                    case "Any": return $"(jsonb_array_length(coalesce({left},'[]')) > 0)";
 | 
			
		||||
@@ -137,6 +138,7 @@ namespace FreeSql.PostgreSQL
 | 
			
		||||
                        }
 | 
			
		||||
                        if (objType.FullName == typeof(Dictionary<string, string>).FullName)
 | 
			
		||||
                        {
 | 
			
		||||
                            left = objExp == null ? null : getExp(objExp);
 | 
			
		||||
                            switch (callExp.Method.Name)
 | 
			
		||||
                            {
 | 
			
		||||
                                case "Contains":
 | 
			
		||||
@@ -154,24 +156,30 @@ namespace FreeSql.PostgreSQL
 | 
			
		||||
                        switch (callExp.Method.Name)
 | 
			
		||||
                        {
 | 
			
		||||
                            case "Any":
 | 
			
		||||
                                left = objExp == null ? null : getExp(objExp);
 | 
			
		||||
                                if (left.StartsWith("(") || left.EndsWith(")")) left = $"array[{left.TrimStart('(').TrimEnd(')')}]";
 | 
			
		||||
                                return $"(case when {left} is null then 0 else array_length({left},1) end > 0)";
 | 
			
		||||
                            case "Contains":
 | 
			
		||||
                                tsc?.SetMapTypeTmp(null);
 | 
			
		||||
                                var args1 = getExp(callExp.Arguments[argIndex]);
 | 
			
		||||
                                var oldMapType = tsc?.SetMapTypeReturnOld(tsc?.mapTypeTmp);
 | 
			
		||||
                                left = objExp == null ? null : getExp(objExp);
 | 
			
		||||
                                tsc.SetMapTypeReturnOld(oldMapType);
 | 
			
		||||
                                //判断 in 或 array @> array
 | 
			
		||||
                                var right1 = getExp(callExp.Arguments[argIndex]);
 | 
			
		||||
                                if (left.StartsWith("array[") || left.EndsWith("]"))
 | 
			
		||||
                                    return $"{right1} in ({left.Substring(6, left.Length - 7)})";
 | 
			
		||||
                                    return $"{args1} in ({left.Substring(6, left.Length - 7)})";
 | 
			
		||||
                                if (left.StartsWith("(") || left.EndsWith(")"))
 | 
			
		||||
                                    return $"{right1} in {left}";
 | 
			
		||||
                                if (right1.StartsWith("(") || right1.EndsWith(")")) right1 = $"array[{right1.TrimStart('(').TrimEnd(')')}]";
 | 
			
		||||
                                right1 = $"array[{right1}]";
 | 
			
		||||
                                    return $"{args1} in {left}";
 | 
			
		||||
                                if (args1.StartsWith("(") || args1.EndsWith(")")) args1 = $"array[{args1.TrimStart('(').TrimEnd(')')}]";
 | 
			
		||||
                                args1 = $"array[{args1}]";
 | 
			
		||||
                                if (objExp != null)
 | 
			
		||||
                                {
 | 
			
		||||
                                    var dbinfo = _common._orm.CodeFirst.GetDbInfo(objExp.Type);
 | 
			
		||||
                                    if (dbinfo.HasValue) right1 = $"{right1}::{dbinfo.Value.dbtype}";
 | 
			
		||||
                                    if (dbinfo.HasValue) args1 = $"{args1}::{dbinfo.Value.dbtype}";
 | 
			
		||||
                                }
 | 
			
		||||
                                return $"({left} @> {right1})";
 | 
			
		||||
                                return $"({left} @> {args1})";
 | 
			
		||||
                            case "Concat":
 | 
			
		||||
                                left = objExp == null ? null : getExp(objExp);
 | 
			
		||||
                                if (left.StartsWith("(") || left.EndsWith(")")) left = $"array[{left.TrimStart('(').TrimEnd(')')}]";
 | 
			
		||||
                                var right2 = getExp(callExp.Arguments[argIndex]);
 | 
			
		||||
                                if (right2.StartsWith("(") || right2.EndsWith(")")) right2 = $"array[{right2.TrimStart('(').TrimEnd(')')}]";
 | 
			
		||||
@@ -180,6 +188,7 @@ namespace FreeSql.PostgreSQL
 | 
			
		||||
                            case "GetLongLength":
 | 
			
		||||
                            case "Length":
 | 
			
		||||
                            case "Count":
 | 
			
		||||
                                left = objExp == null ? null : getExp(objExp);
 | 
			
		||||
                                if (left.StartsWith("(") || left.EndsWith(")")) left = $"array[{left.TrimStart('(').TrimEnd(')')}]";
 | 
			
		||||
                                return $"case when {left} is null then 0 else array_length({left},1) end";
 | 
			
		||||
                        }
 | 
			
		||||
@@ -494,7 +503,7 @@ namespace FreeSql.PostgreSQL
 | 
			
		||||
                    case "AddTicks": return $"(({left})::timestamp+(({args1})/10||' microseconds')::interval)";
 | 
			
		||||
                    case "AddYears": return $"(({left})::timestamp+(({args1})||' year')::interval)";
 | 
			
		||||
                    case "Subtract":
 | 
			
		||||
                        switch ((exp.Arguments[0].Type.IsNullableType() ? exp.Arguments[0].Type.GenericTypeArguments.FirstOrDefault() : exp.Arguments[0].Type).FullName)
 | 
			
		||||
                        switch ((exp.Arguments[0].Type.IsNullableType() ? exp.Arguments[0].Type.GetGenericArguments().FirstOrDefault() : exp.Arguments[0].Type).FullName)
 | 
			
		||||
                        {
 | 
			
		||||
                            case "System.DateTime": return $"(extract(epoch from ({left})::timestamp-({args1})::timestamp)*1000000)";
 | 
			
		||||
                            case "System.TimeSpan": return $"(({left})::timestamp-(({args1})||' microseconds')::interval)";
 | 
			
		||||
 
 | 
			
		||||
@@ -30,7 +30,7 @@ namespace FreeSql.SqlServer
 | 
			
		||||
        public override object AddslashesProcessParam(object param, Type mapType)
 | 
			
		||||
        {
 | 
			
		||||
            if (param == null) return "NULL";
 | 
			
		||||
            if (mapType != null && mapType != param.GetType())
 | 
			
		||||
            if (mapType != null && mapType != param.GetType() && (param is IEnumerable == false || mapType.IsArrayOrList()))
 | 
			
		||||
                param = Utils.GetDataReaderValue(mapType, param);
 | 
			
		||||
            if (param is bool || param is bool?)
 | 
			
		||||
                return (bool)param ? 1 : 0;
 | 
			
		||||
 
 | 
			
		||||
@@ -103,14 +103,18 @@ namespace FreeSql.SqlServer
 | 
			
		||||
                        argIndex++;
 | 
			
		||||
                    }
 | 
			
		||||
                    if (objType == null) objType = callExp.Method.DeclaringType;
 | 
			
		||||
                    if (objType != null || objType.IsArray || typeof(IList).IsAssignableFrom(callExp.Method.DeclaringType))
 | 
			
		||||
                    if (objType != null || objType.IsArrayOrList())
 | 
			
		||||
                    {
 | 
			
		||||
                        tsc?.SetMapTypeTmp(null);
 | 
			
		||||
                        var args1 = getExp(callExp.Arguments[argIndex]);
 | 
			
		||||
                        var oldMapType = tsc?.SetMapTypeReturnOld(tsc?.mapTypeTmp);
 | 
			
		||||
                        var left = objExp == null ? null : getExp(objExp);
 | 
			
		||||
                        tsc.SetMapTypeReturnOld(oldMapType);
 | 
			
		||||
                        switch (callExp.Method.Name)
 | 
			
		||||
                        {
 | 
			
		||||
                            case "Contains":
 | 
			
		||||
                                //判断 in
 | 
			
		||||
                                return $"({getExp(callExp.Arguments[argIndex])}) in {left}";
 | 
			
		||||
                                return $"({args1}) in {left}";
 | 
			
		||||
                        }
 | 
			
		||||
                    }
 | 
			
		||||
                    break;
 | 
			
		||||
 
 | 
			
		||||
@@ -29,7 +29,7 @@ namespace FreeSql.Sqlite
 | 
			
		||||
        public override object AddslashesProcessParam(object param, Type mapType)
 | 
			
		||||
        {
 | 
			
		||||
            if (param == null) return "NULL";
 | 
			
		||||
            if (mapType != null && mapType != param.GetType())
 | 
			
		||||
            if (mapType != null && mapType != param.GetType() && (param is IEnumerable == false || mapType.IsArrayOrList()))
 | 
			
		||||
                param = Utils.GetDataReaderValue(mapType, param);
 | 
			
		||||
            if (param is bool || param is bool?)
 | 
			
		||||
                return (bool)param ? 1 : 0;
 | 
			
		||||
 
 | 
			
		||||
@@ -99,14 +99,18 @@ namespace FreeSql.Sqlite
 | 
			
		||||
                        argIndex++;
 | 
			
		||||
                    }
 | 
			
		||||
                    if (objType == null) objType = callExp.Method.DeclaringType;
 | 
			
		||||
                    if (objType != null || objType.IsArray || typeof(IList).IsAssignableFrom(callExp.Method.DeclaringType))
 | 
			
		||||
                    if (objType != null || objType.IsArrayOrList())
 | 
			
		||||
                    {
 | 
			
		||||
                        tsc?.SetMapTypeTmp(null);
 | 
			
		||||
                        var args1 = getExp(callExp.Arguments[argIndex]);
 | 
			
		||||
                        var oldMapType = tsc?.SetMapTypeReturnOld(tsc?.mapTypeTmp);
 | 
			
		||||
                        var left = objExp == null ? null : getExp(objExp);
 | 
			
		||||
                        tsc.SetMapTypeReturnOld(oldMapType);
 | 
			
		||||
                        switch (callExp.Method.Name)
 | 
			
		||||
                        {
 | 
			
		||||
                            case "Contains":
 | 
			
		||||
                                //判断 in
 | 
			
		||||
                                return $"({getExp(callExp.Arguments[argIndex])}) in {left}";
 | 
			
		||||
                                return $"({args1}) in {left}";
 | 
			
		||||
                        }
 | 
			
		||||
                    }
 | 
			
		||||
                    break;
 | 
			
		||||
 
 | 
			
		||||
		Reference in New Issue
	
	Block a user