- 修复 MapType 属性的表达式解析 数组.Contains 得到是映射之前的值 bug;

- 修复 MapType 属性 与 IncludeMany 变异功能未映射处理的 bug;
This commit is contained in:
28810 2019-11-17 17:14:00 +08:00
parent 330eb40285
commit 7c42c67797
24 changed files with 249 additions and 54 deletions

View File

@ -1,5 +1,6 @@
using FreeSql; using FreeSql;
using System; using System;
using System.Collections;
using System.Collections.Concurrent; using System.Collections.Concurrent;
using System.Collections.Generic; using System.Collections.Generic;
using System.ComponentModel; 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 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 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 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; 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)); internal static string NotNullAndConcat(this string that, params object[] args) => string.IsNullOrEmpty(that) ? null : string.Concat(new object[] { that }.Concat(args));

View File

@ -1996,6 +1996,137 @@
<param name="parms"></param> <param name="parms"></param>
<returns></returns> <returns></returns>
</member> </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&lt;User&gt;("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&lt;User&gt;("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&lt;User&gt;("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&lt;User&gt;("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"> <member name="P:FreeSql.IAop.ParseExpression">
<summary> <summary>
可自定义解析表达式 可自定义解析表达式

View File

@ -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} 被忽略,请检查 IsIgnore 设置,确认 get/set 为 public");
throw new ArgumentException($"{tb.DbName} 找不到列 {memberExp.Member.Name}"); throw new ArgumentException($"{tb.DbName} 找不到列 {memberExp.Member.Name}");
} }
var curcol = tb.ColumnsByCs[memberExp.Member.Name];
if (tsc._selectColumnMap != null) if (tsc._selectColumnMap != null)
{ tsc._selectColumnMap.Add(new SelectColumnInfo { Table = null, Column = curcol });
tsc._selectColumnMap.Add(new SelectColumnInfo { Table = null, Column = tb.ColumnsByCs[memberExp.Member.Name] }); var name = curcol.Attribute.Name;
}
var name = tb.ColumnsByCs[memberExp.Member.Name].Attribute.Name;
if (tsc.isQuoteName) name = _common.QuoteSqlName(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; if (string.IsNullOrEmpty(tsc.alias001)) return name;
return $"{tsc.alias001}.{name}"; return $"{tsc.alias001}.{name}";
} }
@ -1098,7 +1098,8 @@ namespace FreeSql.Internal
tsc._selectColumnMap.Add(new SelectColumnInfo { Table = find2, Column = col2 }); tsc._selectColumnMap.Add(new SelectColumnInfo { Table = find2, Column = col2 });
return ""; 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; break;
case ExpressionType.Call: break; case ExpressionType.Call: break;
} }
@ -1150,10 +1151,22 @@ namespace FreeSql.Internal
public bool isDisableDiyParse { get; set; } public bool isDisableDiyParse { get; set; }
public ExpressionStyle style { get; set; } public ExpressionStyle style { get; set; }
public Type mapType { get; set; } public Type mapType { get; set; }
public Type mapTypeTmp { get; set; }
public TableInfo currentTable { get; set; } public TableInfo currentTable { get; set; }
public List<LambdaExpression> whereCascadeExpression { get; set; } public List<LambdaExpression> whereCascadeExpression { get; set; }
public string alias001 { 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) public ExpTSC CloneSetgetSelectGroupingMapStringAndgetSelectGroupingMapStringAndtbtype(List<SelectColumnInfo> v1, Func<Expression[], string> v2, SelectTableInfoType v3)
{ {
return new ExpTSC return new ExpTSC

View File

@ -605,7 +605,7 @@ namespace FreeSql.Internal.CommonProvider
for (var z = 0; z < tbref.Columns.Count; z++) for (var z = 0; z < tbref.Columns.Count; z++)
{ {
if (z > 0) sbWhereOne.Append(" AND "); 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(")"); sbWhereOne.Append(")");
var whereOne = sbWhereOne.ToString(); var whereOne = sbWhereOne.ToString();
@ -797,7 +797,7 @@ namespace FreeSql.Internal.CommonProvider
for (var z = 0; z < tbref.Columns.Count; z++) for (var z = 0; z < tbref.Columns.Count; z++)
{ {
if (z > 0) sbWhereOne.Append(" AND "); 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(")"); sbWhereOne.Append(")");
var whereOne = sbWhereOne.ToString(); var whereOne = sbWhereOne.ToString();
@ -825,7 +825,7 @@ namespace FreeSql.Internal.CommonProvider
subSelect._where.Clear(); subSelect._where.Clear();
if (tbref.Columns.Count == 1) 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 else
{ {

View File

@ -31,7 +31,7 @@ namespace FreeSql.MySql
public override object AddslashesProcessParam(object param, Type mapType) public override object AddslashesProcessParam(object param, Type mapType)
{ {
if (param == null) return "NULL"; 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); param = Utils.GetDataReaderValue(mapType, param);
if (param is bool || param is bool?) if (param is bool || param is bool?)
return (bool)param ? 1 : 0; return (bool)param ? 1 : 0;

View File

@ -99,14 +99,18 @@ namespace FreeSql.MySql
argIndex++; argIndex++;
} }
if (objType == null) objType = callExp.Method.DeclaringType; 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); var left = objExp == null ? null : getExp(objExp);
tsc.SetMapTypeReturnOld(oldMapType);
switch (callExp.Method.Name) switch (callExp.Method.Name)
{ {
case "Contains": case "Contains":
//判断 in //判断 in
return $"({getExp(callExp.Arguments[argIndex])}) in {left}"; return $"({args1}) in {left}";
} }
} }
break; break;

View File

@ -32,7 +32,7 @@ namespace FreeSql.Odbc.Default
public override object AddslashesProcessParam(object param, Type mapType) public override object AddslashesProcessParam(object param, Type mapType)
{ {
if (param == null) return "NULL"; 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); param = Utils.GetDataReaderValue(mapType, param);
if (param is bool || param is bool?) if (param is bool || param is bool?)
return (bool)param ? 1 : 0; return (bool)param ? 1 : 0;

View File

@ -106,14 +106,18 @@ namespace FreeSql.Odbc.Default
argIndex++; argIndex++;
} }
if (objType == null) objType = callExp.Method.DeclaringType; 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); var left = objExp == null ? null : getExp(objExp);
tsc.SetMapTypeReturnOld(oldMapType);
switch (callExp.Method.Name) switch (callExp.Method.Name)
{ {
case "Contains": case "Contains":
//判断 in //判断 in
return $"({getExp(callExp.Arguments[argIndex])}) in {left}"; return $"({args1}) in {left}";
} }
} }
break; break;

View File

@ -31,7 +31,7 @@ namespace FreeSql.Odbc.MySql
public override object AddslashesProcessParam(object param, Type mapType) public override object AddslashesProcessParam(object param, Type mapType)
{ {
if (param == null) return "NULL"; 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); param = Utils.GetDataReaderValue(mapType, param);
if (param is bool || param is bool?) if (param is bool || param is bool?)
return (bool)param ? 1 : 0; return (bool)param ? 1 : 0;

View File

@ -99,14 +99,18 @@ namespace FreeSql.Odbc.MySql
argIndex++; argIndex++;
} }
if (objType == null) objType = callExp.Method.DeclaringType; 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); var left = objExp == null ? null : getExp(objExp);
tsc.SetMapTypeReturnOld(oldMapType);
switch (callExp.Method.Name) switch (callExp.Method.Name)
{ {
case "Contains": case "Contains":
//判断 in //判断 in
return $"({getExp(callExp.Arguments[argIndex])}) in {left}"; return $"({args1}) in {left}";
} }
} }
break; break;

View File

@ -30,7 +30,7 @@ namespace FreeSql.Odbc.Oracle
public override object AddslashesProcessParam(object param, Type mapType) public override object AddslashesProcessParam(object param, Type mapType)
{ {
if (param == null) return "NULL"; 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); param = Utils.GetDataReaderValue(mapType, param);
if (param is bool || param is bool?) if (param is bool || param is bool?)
return (bool)param ? 1 : 0; return (bool)param ? 1 : 0;

View File

@ -99,14 +99,18 @@ namespace FreeSql.Odbc.Oracle
argIndex++; argIndex++;
} }
if (objType == null) objType = callExp.Method.DeclaringType; 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); var left = objExp == null ? null : getExp(objExp);
tsc.SetMapTypeReturnOld(oldMapType);
switch (callExp.Method.Name) switch (callExp.Method.Name)
{ {
case "Contains": case "Contains":
//判断 in //判断 in
return $"({getExp(callExp.Arguments[argIndex])}) in {left}"; return $"({args1}) in {left}";
} }
} }
break; break;

View File

@ -32,7 +32,7 @@ namespace FreeSql.Odbc.PostgreSQL
public override object AddslashesProcessParam(object param, Type mapType) public override object AddslashesProcessParam(object param, Type mapType)
{ {
if (param == null) return "NULL"; 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); param = Utils.GetDataReaderValue(mapType, param);
if (param is bool || param is bool?) if (param is bool || param is bool?)
return (bool)param ? "'t'" : "'f'"; return (bool)param ? "'t'" : "'f'";

View File

@ -103,11 +103,12 @@ namespace FreeSql.Odbc.PostgreSQL
argIndex++; argIndex++;
} }
if (objType == null) objType = callExp.Method.DeclaringType; 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) if (objType.FullName == typeof(Dictionary<string, string>).FullName)
{ {
left = objExp == null ? null : getExp(objExp);
switch (callExp.Method.Name) switch (callExp.Method.Name)
{ {
case "Contains": case "Contains":
@ -125,24 +126,30 @@ namespace FreeSql.Odbc.PostgreSQL
switch (callExp.Method.Name) switch (callExp.Method.Name)
{ {
case "Any": case "Any":
left = objExp == null ? null : getExp(objExp);
if (left.StartsWith("(") || left.EndsWith(")")) left = $"array[{left.TrimStart('(').TrimEnd(')')}]"; 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)"; return $"(case when {left} is null then 0 else array_length({left},1) end > 0)";
case "Contains": 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 //判断 in 或 array @> array
var right1 = getExp(callExp.Arguments[argIndex]);
if (left.StartsWith("array[") || left.EndsWith("]")) 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(")")) if (left.StartsWith("(") || left.EndsWith(")"))
return $"{right1} in {left}"; return $"{args1} in {left}";
if (right1.StartsWith("(") || right1.EndsWith(")")) right1 = $"array[{right1.TrimStart('(').TrimEnd(')')}]"; if (args1.StartsWith("(") || args1.EndsWith(")")) args1 = $"array[{args1.TrimStart('(').TrimEnd(')')}]";
right1 = $"array[{right1}]"; args1 = $"array[{args1}]";
if (objExp != null) if (objExp != null)
{ {
var dbinfo = _common._orm.CodeFirst.GetDbInfo(objExp.Type); 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": case "Concat":
left = objExp == null ? null : getExp(objExp);
if (left.StartsWith("(") || left.EndsWith(")")) left = $"array[{left.TrimStart('(').TrimEnd(')')}]"; if (left.StartsWith("(") || left.EndsWith(")")) left = $"array[{left.TrimStart('(').TrimEnd(')')}]";
var right2 = getExp(callExp.Arguments[argIndex]); var right2 = getExp(callExp.Arguments[argIndex]);
if (right2.StartsWith("(") || right2.EndsWith(")")) right2 = $"array[{right2.TrimStart('(').TrimEnd(')')}]"; if (right2.StartsWith("(") || right2.EndsWith(")")) right2 = $"array[{right2.TrimStart('(').TrimEnd(')')}]";
@ -151,6 +158,7 @@ namespace FreeSql.Odbc.PostgreSQL
case "GetLongLength": case "GetLongLength":
case "Length": case "Length":
case "Count": case "Count":
left = objExp == null ? null : getExp(objExp);
if (left.StartsWith("(") || left.EndsWith(")")) left = $"array[{left.TrimStart('(').TrimEnd(')')}]"; if (left.StartsWith("(") || left.EndsWith(")")) left = $"array[{left.TrimStart('(').TrimEnd(')')}]";
return $"case when {left} is null then 0 else array_length({left},1) end"; return $"case when {left} is null then 0 else array_length({left},1) end";
} }

View File

@ -30,7 +30,7 @@ namespace FreeSql.Odbc.SqlServer
public override object AddslashesProcessParam(object param, Type mapType) public override object AddslashesProcessParam(object param, Type mapType)
{ {
if (param == null) return "NULL"; 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); param = Utils.GetDataReaderValue(mapType, param);
if (param is bool || param is bool?) if (param is bool || param is bool?)
return (bool)param ? 1 : 0; return (bool)param ? 1 : 0;

View File

@ -103,14 +103,18 @@ namespace FreeSql.Odbc.SqlServer
argIndex++; argIndex++;
} }
if (objType == null) objType = callExp.Method.DeclaringType; 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); var left = objExp == null ? null : getExp(objExp);
tsc.SetMapTypeReturnOld(oldMapType);
switch (callExp.Method.Name) switch (callExp.Method.Name)
{ {
case "Contains": case "Contains":
//判断 in //判断 in
return $"({getExp(callExp.Arguments[argIndex])}) in {left}"; return $"({args1}) in {left}";
} }
} }
break; break;

View File

@ -30,7 +30,7 @@ namespace FreeSql.Oracle
public override object AddslashesProcessParam(object param, Type mapType) public override object AddslashesProcessParam(object param, Type mapType)
{ {
if (param == null) return "NULL"; 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); param = Utils.GetDataReaderValue(mapType, param);
if (param is bool || param is bool?) if (param is bool || param is bool?)
return (bool)param ? 1 : 0; return (bool)param ? 1 : 0;

View File

@ -99,14 +99,18 @@ namespace FreeSql.Oracle
argIndex++; argIndex++;
} }
if (objType == null) objType = callExp.Method.DeclaringType; 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); var left = objExp == null ? null : getExp(objExp);
tsc.SetMapTypeReturnOld(oldMapType);
switch (callExp.Method.Name) switch (callExp.Method.Name)
{ {
case "Contains": case "Contains":
//判断 in //判断 in
return $"({getExp(callExp.Arguments[argIndex])}) in {left}"; return $"({args1}) in {left}";
} }
} }
break; break;

View File

@ -33,9 +33,9 @@ namespace FreeSql.PostgreSQL
public override object AddslashesProcessParam(object param, Type mapType) public override object AddslashesProcessParam(object param, Type mapType)
{ {
if (param == null) return "NULL"; 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); param = Utils.GetDataReaderValue(mapType, param);
bool isdic = false; bool isdic;
if (param is bool || param is bool?) if (param is bool || param is bool?)
return (bool)param ? "'t'" : "'f'"; return (bool)param ? "'t'" : "'f'";
else if (param is string || param is char) else if (param is string || param is char)

View File

@ -104,14 +104,15 @@ namespace FreeSql.PostgreSQL
argIndex++; argIndex++;
} }
if (objType == null) objType = callExp.Method.DeclaringType; 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) switch (objType.FullName)
{ {
case "Newtonsoft.Json.Linq.JToken": case "Newtonsoft.Json.Linq.JToken":
case "Newtonsoft.Json.Linq.JObject": case "Newtonsoft.Json.Linq.JObject":
case "Newtonsoft.Json.Linq.JArray": case "Newtonsoft.Json.Linq.JArray":
left = objExp == null ? null : getExp(objExp);
switch (callExp.Method.Name) switch (callExp.Method.Name)
{ {
case "Any": return $"(jsonb_array_length(coalesce({left},'[]')) > 0)"; case "Any": return $"(jsonb_array_length(coalesce({left},'[]')) > 0)";
@ -137,6 +138,7 @@ namespace FreeSql.PostgreSQL
} }
if (objType.FullName == typeof(Dictionary<string, string>).FullName) if (objType.FullName == typeof(Dictionary<string, string>).FullName)
{ {
left = objExp == null ? null : getExp(objExp);
switch (callExp.Method.Name) switch (callExp.Method.Name)
{ {
case "Contains": case "Contains":
@ -154,24 +156,30 @@ namespace FreeSql.PostgreSQL
switch (callExp.Method.Name) switch (callExp.Method.Name)
{ {
case "Any": case "Any":
left = objExp == null ? null : getExp(objExp);
if (left.StartsWith("(") || left.EndsWith(")")) left = $"array[{left.TrimStart('(').TrimEnd(')')}]"; 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)"; return $"(case when {left} is null then 0 else array_length({left},1) end > 0)";
case "Contains": 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 //判断 in 或 array @> array
var right1 = getExp(callExp.Arguments[argIndex]);
if (left.StartsWith("array[") || left.EndsWith("]")) 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(")")) if (left.StartsWith("(") || left.EndsWith(")"))
return $"{right1} in {left}"; return $"{args1} in {left}";
if (right1.StartsWith("(") || right1.EndsWith(")")) right1 = $"array[{right1.TrimStart('(').TrimEnd(')')}]"; if (args1.StartsWith("(") || args1.EndsWith(")")) args1 = $"array[{args1.TrimStart('(').TrimEnd(')')}]";
right1 = $"array[{right1}]"; args1 = $"array[{args1}]";
if (objExp != null) if (objExp != null)
{ {
var dbinfo = _common._orm.CodeFirst.GetDbInfo(objExp.Type); 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": case "Concat":
left = objExp == null ? null : getExp(objExp);
if (left.StartsWith("(") || left.EndsWith(")")) left = $"array[{left.TrimStart('(').TrimEnd(')')}]"; if (left.StartsWith("(") || left.EndsWith(")")) left = $"array[{left.TrimStart('(').TrimEnd(')')}]";
var right2 = getExp(callExp.Arguments[argIndex]); var right2 = getExp(callExp.Arguments[argIndex]);
if (right2.StartsWith("(") || right2.EndsWith(")")) right2 = $"array[{right2.TrimStart('(').TrimEnd(')')}]"; if (right2.StartsWith("(") || right2.EndsWith(")")) right2 = $"array[{right2.TrimStart('(').TrimEnd(')')}]";
@ -180,6 +188,7 @@ namespace FreeSql.PostgreSQL
case "GetLongLength": case "GetLongLength":
case "Length": case "Length":
case "Count": case "Count":
left = objExp == null ? null : getExp(objExp);
if (left.StartsWith("(") || left.EndsWith(")")) left = $"array[{left.TrimStart('(').TrimEnd(')')}]"; if (left.StartsWith("(") || left.EndsWith(")")) left = $"array[{left.TrimStart('(').TrimEnd(')')}]";
return $"case when {left} is null then 0 else array_length({left},1) end"; 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 "AddTicks": return $"(({left})::timestamp+(({args1})/10||' microseconds')::interval)";
case "AddYears": return $"(({left})::timestamp+(({args1})||' year')::interval)"; case "AddYears": return $"(({left})::timestamp+(({args1})||' year')::interval)";
case "Subtract": 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.DateTime": return $"(extract(epoch from ({left})::timestamp-({args1})::timestamp)*1000000)";
case "System.TimeSpan": return $"(({left})::timestamp-(({args1})||' microseconds')::interval)"; case "System.TimeSpan": return $"(({left})::timestamp-(({args1})||' microseconds')::interval)";

View File

@ -30,7 +30,7 @@ namespace FreeSql.SqlServer
public override object AddslashesProcessParam(object param, Type mapType) public override object AddslashesProcessParam(object param, Type mapType)
{ {
if (param == null) return "NULL"; 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); param = Utils.GetDataReaderValue(mapType, param);
if (param is bool || param is bool?) if (param is bool || param is bool?)
return (bool)param ? 1 : 0; return (bool)param ? 1 : 0;

View File

@ -103,14 +103,18 @@ namespace FreeSql.SqlServer
argIndex++; argIndex++;
} }
if (objType == null) objType = callExp.Method.DeclaringType; 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); var left = objExp == null ? null : getExp(objExp);
tsc.SetMapTypeReturnOld(oldMapType);
switch (callExp.Method.Name) switch (callExp.Method.Name)
{ {
case "Contains": case "Contains":
//判断 in //判断 in
return $"({getExp(callExp.Arguments[argIndex])}) in {left}"; return $"({args1}) in {left}";
} }
} }
break; break;

View File

@ -29,7 +29,7 @@ namespace FreeSql.Sqlite
public override object AddslashesProcessParam(object param, Type mapType) public override object AddslashesProcessParam(object param, Type mapType)
{ {
if (param == null) return "NULL"; 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); param = Utils.GetDataReaderValue(mapType, param);
if (param is bool || param is bool?) if (param is bool || param is bool?)
return (bool)param ? 1 : 0; return (bool)param ? 1 : 0;

View File

@ -99,14 +99,18 @@ namespace FreeSql.Sqlite
argIndex++; argIndex++;
} }
if (objType == null) objType = callExp.Method.DeclaringType; 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); var left = objExp == null ? null : getExp(objExp);
tsc.SetMapTypeReturnOld(oldMapType);
switch (callExp.Method.Name) switch (callExp.Method.Name)
{ {
case "Contains": case "Contains":
//判断 in //判断 in
return $"({getExp(callExp.Arguments[argIndex])}) in {left}"; return $"({args1}) in {left}";
} }
} }
break; break;