From 7c42c6779750d69cfe1ca9d74c7b23eb79d1b948 Mon Sep 17 00:00:00 2001
From: 28810 <28810@YEXIANGQIN>
Date: Sun, 17 Nov 2019 17:14:00 +0800
Subject: [PATCH] =?UTF-8?q?-=20=E4=BF=AE=E5=A4=8D=20MapType=20=E5=B1=9E?=
=?UTF-8?q?=E6=80=A7=E7=9A=84=E8=A1=A8=E8=BE=BE=E5=BC=8F=E8=A7=A3=E6=9E=90?=
=?UTF-8?q?=20=E6=95=B0=E7=BB=84.Contains=20=E5=BE=97=E5=88=B0=E6=98=AF?=
=?UTF-8?q?=E6=98=A0=E5=B0=84=E4=B9=8B=E5=89=8D=E7=9A=84=E5=80=BC=20bug?=
=?UTF-8?q?=EF=BC=9B=20-=20=E4=BF=AE=E5=A4=8D=20MapType=20=E5=B1=9E?=
=?UTF-8?q?=E6=80=A7=20=E4=B8=8E=20IncludeMany=20=E5=8F=98=E5=BC=82?=
=?UTF-8?q?=E5=8A=9F=E8=83=BD=E6=9C=AA=E6=98=A0=E5=B0=84=E5=A4=84=E7=90=86?=
=?UTF-8?q?=E7=9A=84=20bug=EF=BC=9B?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
---
FreeSql/Extensions/FreeSqlGlobalExtensions.cs | 2 +
FreeSql/FreeSql.xml | 131 ++++++++++++++++++
FreeSql/Internal/CommonExpression.cs | 23 ++-
.../SelectProvider/Select1Provider.cs | 6 +-
.../MySqlAdo/MySqlAdo.cs | 2 +-
.../FreeSql.Provider.MySql/MySqlExpression.cs | 8 +-
.../Default/OdbcAdo/OdbcAdo.cs | 2 +-
.../Default/OdbcExpression.cs | 8 +-
.../MySql/OdbcMySqlAdo/OdbcMySqlAdo.cs | 2 +-
.../MySql/OdbcMySqlExpression.cs | 8 +-
.../Oracle/OdbcOracleAdo/OdbcOracleAdo.cs | 2 +-
.../Oracle/OdbcOracleExpression.cs | 8 +-
.../OdbcPostgreSQLAdo/OdbcPostgreSQLAdo.cs | 2 +-
.../PostgreSQL/OdbcPostgreSQLExpression.cs | 26 ++--
.../OdbcSqlServerAdo/OdbcSqlServerAdo.cs | 2 +-
.../SqlServer/OdbcSqlServerExpression.cs | 8 +-
.../OracleAdo/OracleAdo.cs | 2 +-
.../OracleExpression.cs | 8 +-
.../PostgreSQLAdo/PostgreSQLAdo.cs | 4 +-
.../PostgreSQLExpression.cs | 29 ++--
.../SqlServerAdo/SqlServerAdo.cs | 2 +-
.../SqlServerExpression.cs | 8 +-
.../SqliteAdo/SqliteAdo.cs | 2 +-
.../SqliteExpression.cs | 8 +-
24 files changed, 249 insertions(+), 54 deletions(-)
diff --git a/FreeSql/Extensions/FreeSqlGlobalExtensions.cs b/FreeSql/Extensions/FreeSqlGlobalExtensions.cs
index f6d27fac..340f6565 100644
--- a/FreeSql/Extensions/FreeSqlGlobalExtensions.cs
+++ b/FreeSql/Extensions/FreeSqlGlobalExtensions.cs
@@ -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));
diff --git a/FreeSql/FreeSql.xml b/FreeSql/FreeSql.xml
index e436e1d8..185896b3 100644
--- a/FreeSql/FreeSql.xml
+++ b/FreeSql/FreeSql.xml
@@ -1996,6 +1996,137 @@
+
+
+ 查询,若使用读写分离,查询【从库】条件cmdText.StartsWith("SELECT "),否则查询【主库】
+
+
+
+
+
+
+
+
+ 查询,ExecuteReaderAsync(dr => {}, "select * from user where age > @age", new { age = 25 })
+
+
+
+
+
+
+ 查询
+
+
+
+
+
+
+ 查询,ExecuteArrayAsync("select * from user where age > @age", new { age = 25 })
+
+
+
+
+
+
+
+ 查询
+
+
+
+
+
+
+ 查询,ExecuteDataSetAsync("select * from user where age > @age; select 2", new { age = 25 })
+
+
+
+
+
+
+
+ 查询
+
+
+
+
+
+
+ 查询,ExecuteDataTableAsync("select * from user where age > @age", new { age = 25 })
+
+
+
+
+
+
+
+ 在【主库】执行
+
+
+
+
+
+
+
+ 在【主库】执行,ExecuteNonQueryAsync("delete from user where age > @age", new { age = 25 })
+
+
+
+
+
+
+
+ 在【主库】执行
+
+
+
+
+
+
+
+ 在【主库】执行,ExecuteScalarAsync("select 1 from user where age > @age", new { age = 25 })
+
+
+
+
+
+
+
+ 执行SQL返回对象集合,QueryAsync<User>("select * from user where age > @age", new SqlParameter { ParameterName = "age", Value = 25 })
+
+
+
+
+
+
+
+
+
+ 执行SQL返回对象集合,QueryAsync<User>("select * from user where age > @age", new { age = 25 })
+
+
+
+
+
+
+
+
+ 执行SQL返回对象集合,Query<User>("select * from user where age > @age; select * from address", new SqlParameter { ParameterName = "age", Value = 25 })
+
+
+
+
+
+
+
+
+
+ 执行SQL返回对象集合,Query<User>("select * from user where age > @age; select * from address", new { age = 25 })
+
+
+
+
+
+
可自定义解析表达式
diff --git a/FreeSql/Internal/CommonExpression.cs b/FreeSql/Internal/CommonExpression.cs
index 11cf1b65..85720257 100644
--- a/FreeSql/Internal/CommonExpression.cs
+++ b/FreeSql/Internal/CommonExpression.cs
@@ -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 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 v1, Func v2, SelectTableInfoType v3)
{
return new ExpTSC
diff --git a/FreeSql/Internal/CommonProvider/SelectProvider/Select1Provider.cs b/FreeSql/Internal/CommonProvider/SelectProvider/Select1Provider.cs
index 96bee31f..a4e8d8f7 100644
--- a/FreeSql/Internal/CommonProvider/SelectProvider/Select1Provider.cs
+++ b/FreeSql/Internal/CommonProvider/SelectProvider/Select1Provider.cs
@@ -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
{
diff --git a/Providers/FreeSql.Provider.MySql/MySqlAdo/MySqlAdo.cs b/Providers/FreeSql.Provider.MySql/MySqlAdo/MySqlAdo.cs
index 3e0154ac..e061fe23 100644
--- a/Providers/FreeSql.Provider.MySql/MySqlAdo/MySqlAdo.cs
+++ b/Providers/FreeSql.Provider.MySql/MySqlAdo/MySqlAdo.cs
@@ -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;
diff --git a/Providers/FreeSql.Provider.MySql/MySqlExpression.cs b/Providers/FreeSql.Provider.MySql/MySqlExpression.cs
index e91917f3..b795dbaf 100644
--- a/Providers/FreeSql.Provider.MySql/MySqlExpression.cs
+++ b/Providers/FreeSql.Provider.MySql/MySqlExpression.cs
@@ -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;
diff --git a/Providers/FreeSql.Provider.Odbc/Default/OdbcAdo/OdbcAdo.cs b/Providers/FreeSql.Provider.Odbc/Default/OdbcAdo/OdbcAdo.cs
index a2fa7646..b42c5b48 100644
--- a/Providers/FreeSql.Provider.Odbc/Default/OdbcAdo/OdbcAdo.cs
+++ b/Providers/FreeSql.Provider.Odbc/Default/OdbcAdo/OdbcAdo.cs
@@ -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;
diff --git a/Providers/FreeSql.Provider.Odbc/Default/OdbcExpression.cs b/Providers/FreeSql.Provider.Odbc/Default/OdbcExpression.cs
index 50262556..574455f7 100644
--- a/Providers/FreeSql.Provider.Odbc/Default/OdbcExpression.cs
+++ b/Providers/FreeSql.Provider.Odbc/Default/OdbcExpression.cs
@@ -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;
diff --git a/Providers/FreeSql.Provider.Odbc/MySql/OdbcMySqlAdo/OdbcMySqlAdo.cs b/Providers/FreeSql.Provider.Odbc/MySql/OdbcMySqlAdo/OdbcMySqlAdo.cs
index b6ee5b3c..0cd07d54 100644
--- a/Providers/FreeSql.Provider.Odbc/MySql/OdbcMySqlAdo/OdbcMySqlAdo.cs
+++ b/Providers/FreeSql.Provider.Odbc/MySql/OdbcMySqlAdo/OdbcMySqlAdo.cs
@@ -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;
diff --git a/Providers/FreeSql.Provider.Odbc/MySql/OdbcMySqlExpression.cs b/Providers/FreeSql.Provider.Odbc/MySql/OdbcMySqlExpression.cs
index ca13a287..2bcd91b2 100644
--- a/Providers/FreeSql.Provider.Odbc/MySql/OdbcMySqlExpression.cs
+++ b/Providers/FreeSql.Provider.Odbc/MySql/OdbcMySqlExpression.cs
@@ -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;
diff --git a/Providers/FreeSql.Provider.Odbc/Oracle/OdbcOracleAdo/OdbcOracleAdo.cs b/Providers/FreeSql.Provider.Odbc/Oracle/OdbcOracleAdo/OdbcOracleAdo.cs
index b9b4d6f9..1bb9cfe0 100644
--- a/Providers/FreeSql.Provider.Odbc/Oracle/OdbcOracleAdo/OdbcOracleAdo.cs
+++ b/Providers/FreeSql.Provider.Odbc/Oracle/OdbcOracleAdo/OdbcOracleAdo.cs
@@ -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;
diff --git a/Providers/FreeSql.Provider.Odbc/Oracle/OdbcOracleExpression.cs b/Providers/FreeSql.Provider.Odbc/Oracle/OdbcOracleExpression.cs
index cd598adc..1c9f08e4 100644
--- a/Providers/FreeSql.Provider.Odbc/Oracle/OdbcOracleExpression.cs
+++ b/Providers/FreeSql.Provider.Odbc/Oracle/OdbcOracleExpression.cs
@@ -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;
diff --git a/Providers/FreeSql.Provider.Odbc/PostgreSQL/OdbcPostgreSQLAdo/OdbcPostgreSQLAdo.cs b/Providers/FreeSql.Provider.Odbc/PostgreSQL/OdbcPostgreSQLAdo/OdbcPostgreSQLAdo.cs
index 3bef8669..0d7027a6 100644
--- a/Providers/FreeSql.Provider.Odbc/PostgreSQL/OdbcPostgreSQLAdo/OdbcPostgreSQLAdo.cs
+++ b/Providers/FreeSql.Provider.Odbc/PostgreSQL/OdbcPostgreSQLAdo/OdbcPostgreSQLAdo.cs
@@ -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'";
diff --git a/Providers/FreeSql.Provider.Odbc/PostgreSQL/OdbcPostgreSQLExpression.cs b/Providers/FreeSql.Provider.Odbc/PostgreSQL/OdbcPostgreSQLExpression.cs
index 449c1a52..cc7839cb 100644
--- a/Providers/FreeSql.Provider.Odbc/PostgreSQL/OdbcPostgreSQLExpression.cs
+++ b/Providers/FreeSql.Provider.Odbc/PostgreSQL/OdbcPostgreSQLExpression.cs
@@ -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).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";
}
diff --git a/Providers/FreeSql.Provider.Odbc/SqlServer/OdbcSqlServerAdo/OdbcSqlServerAdo.cs b/Providers/FreeSql.Provider.Odbc/SqlServer/OdbcSqlServerAdo/OdbcSqlServerAdo.cs
index 360c7b47..3920f4b6 100644
--- a/Providers/FreeSql.Provider.Odbc/SqlServer/OdbcSqlServerAdo/OdbcSqlServerAdo.cs
+++ b/Providers/FreeSql.Provider.Odbc/SqlServer/OdbcSqlServerAdo/OdbcSqlServerAdo.cs
@@ -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;
diff --git a/Providers/FreeSql.Provider.Odbc/SqlServer/OdbcSqlServerExpression.cs b/Providers/FreeSql.Provider.Odbc/SqlServer/OdbcSqlServerExpression.cs
index f96d7c83..74a752c9 100644
--- a/Providers/FreeSql.Provider.Odbc/SqlServer/OdbcSqlServerExpression.cs
+++ b/Providers/FreeSql.Provider.Odbc/SqlServer/OdbcSqlServerExpression.cs
@@ -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;
diff --git a/Providers/FreeSql.Provider.Oracle/OracleAdo/OracleAdo.cs b/Providers/FreeSql.Provider.Oracle/OracleAdo/OracleAdo.cs
index dc0c4790..8c45bb19 100644
--- a/Providers/FreeSql.Provider.Oracle/OracleAdo/OracleAdo.cs
+++ b/Providers/FreeSql.Provider.Oracle/OracleAdo/OracleAdo.cs
@@ -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;
diff --git a/Providers/FreeSql.Provider.Oracle/OracleExpression.cs b/Providers/FreeSql.Provider.Oracle/OracleExpression.cs
index 80016c64..a5f35911 100644
--- a/Providers/FreeSql.Provider.Oracle/OracleExpression.cs
+++ b/Providers/FreeSql.Provider.Oracle/OracleExpression.cs
@@ -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;
diff --git a/Providers/FreeSql.Provider.PostgreSQL/PostgreSQLAdo/PostgreSQLAdo.cs b/Providers/FreeSql.Provider.PostgreSQL/PostgreSQLAdo/PostgreSQLAdo.cs
index 0c3b492e..eee3e5c9 100644
--- a/Providers/FreeSql.Provider.PostgreSQL/PostgreSQLAdo/PostgreSQLAdo.cs
+++ b/Providers/FreeSql.Provider.PostgreSQL/PostgreSQLAdo/PostgreSQLAdo.cs
@@ -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)
diff --git a/Providers/FreeSql.Provider.PostgreSQL/PostgreSQLExpression.cs b/Providers/FreeSql.Provider.PostgreSQL/PostgreSQLExpression.cs
index 6c203306..4507cebe 100644
--- a/Providers/FreeSql.Provider.PostgreSQL/PostgreSQLExpression.cs
+++ b/Providers/FreeSql.Provider.PostgreSQL/PostgreSQLExpression.cs
@@ -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).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)";
diff --git a/Providers/FreeSql.Provider.SqlServer/SqlServerAdo/SqlServerAdo.cs b/Providers/FreeSql.Provider.SqlServer/SqlServerAdo/SqlServerAdo.cs
index adfc89be..c6799a13 100644
--- a/Providers/FreeSql.Provider.SqlServer/SqlServerAdo/SqlServerAdo.cs
+++ b/Providers/FreeSql.Provider.SqlServer/SqlServerAdo/SqlServerAdo.cs
@@ -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;
diff --git a/Providers/FreeSql.Provider.SqlServer/SqlServerExpression.cs b/Providers/FreeSql.Provider.SqlServer/SqlServerExpression.cs
index 4b0b0bb1..c775851f 100644
--- a/Providers/FreeSql.Provider.SqlServer/SqlServerExpression.cs
+++ b/Providers/FreeSql.Provider.SqlServer/SqlServerExpression.cs
@@ -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;
diff --git a/Providers/FreeSql.Provider.Sqlite/SqliteAdo/SqliteAdo.cs b/Providers/FreeSql.Provider.Sqlite/SqliteAdo/SqliteAdo.cs
index d8df365d..9e27fc13 100644
--- a/Providers/FreeSql.Provider.Sqlite/SqliteAdo/SqliteAdo.cs
+++ b/Providers/FreeSql.Provider.Sqlite/SqliteAdo/SqliteAdo.cs
@@ -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;
diff --git a/Providers/FreeSql.Provider.Sqlite/SqliteExpression.cs b/Providers/FreeSql.Provider.Sqlite/SqliteExpression.cs
index 9f451e0b..ce13a196 100644
--- a/Providers/FreeSql.Provider.Sqlite/SqliteExpression.cs
+++ b/Providers/FreeSql.Provider.Sqlite/SqliteExpression.cs
@@ -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;