From efdc7c8c5d84dc6f81f0c44b9a538f7f5ad0b84e Mon Sep 17 00:00:00 2001
From: 28810 <28810@YEXIANGQIN>
Date: Wed, 20 Nov 2019 03:34:55 +0800
Subject: [PATCH] =?UTF-8?q?-=20=E5=85=BC=E5=AE=B9=20SqlServer=20varchar/nv?=
=?UTF-8?q?archar=20=E8=A1=A8=E8=BE=BE=E5=BC=8F=E8=A7=A3=E6=9E=90=EF=BC=8C?=
=?UTF-8?q?=E5=88=86=E5=88=AB=E8=A7=A3=E6=9E=90=E4=B8=BA=EF=BC=9AN''=20?=
=?UTF-8?q?=E5=92=8C=20''=EF=BC=9B?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
---
FreeSql.DbContext/FreeSql.DbContext.xml | 7 -
.../SqlServerExpression/OtherTest.cs | 61 +++++++-
.../SqlServerExpression/StringTest.cs | 135 ++++++++++++++++++
FreeSql/FreeSql.xml | 131 +++++++++++++++++
FreeSql/Internal/CommonExpression.cs | 54 ++++---
.../AdoProvider/AdoProviderUtils.cs | 7 +-
.../MySqlAdo/MySqlAdo.cs | 5 +-
.../FreeSql.Provider.MySql/MySqlExpression.cs | 6 +-
.../Default/OdbcAdapter.cs | 5 +-
.../Default/OdbcAdo/OdbcAdo.cs | 7 +-
.../Default/OdbcExpression.cs | 6 +-
.../MySql/OdbcMySqlAdo/OdbcMySqlAdo.cs | 5 +-
.../MySql/OdbcMySqlExpression.cs | 6 +-
.../Oracle/OdbcOracleAdo/OdbcOracleAdo.cs | 5 +-
.../Oracle/OdbcOracleExpression.cs | 6 +-
.../OdbcPostgreSQLAdo/OdbcPostgreSQLAdo.cs | 5 +-
.../PostgreSQL/OdbcPostgreSQLExpression.cs | 6 +-
.../OdbcSqlServerAdo/OdbcSqlServerAdo.cs | 12 +-
.../SqlServer/OdbcSqlServerExpression.cs | 6 +-
.../OracleAdo/OracleAdo.cs | 5 +-
.../OracleExpression.cs | 6 +-
.../PostgreSQLAdo/PostgreSQLAdo.cs | 5 +-
.../PostgreSQLExpression.cs | 6 +-
.../SqlServerAdo/SqlServerAdo.cs | 12 +-
.../SqlServerExpression.cs | 6 +-
.../SqliteAdo/SqliteAdo.cs | 5 +-
.../SqliteExpression.cs | 6 +-
27 files changed, 440 insertions(+), 86 deletions(-)
diff --git a/FreeSql.DbContext/FreeSql.DbContext.xml b/FreeSql.DbContext/FreeSql.DbContext.xml
index 1a43f59e..9c0597d5 100644
--- a/FreeSql.DbContext/FreeSql.DbContext.xml
+++ b/FreeSql.DbContext/FreeSql.DbContext.xml
@@ -106,13 +106,6 @@
清空状态数据
-
-
- 根据 lambda 条件删除数据
-
-
-
-
添加
diff --git a/FreeSql.Tests/FreeSql.Tests/SqlServer/SqlServerExpression/OtherTest.cs b/FreeSql.Tests/FreeSql.Tests/SqlServer/SqlServerExpression/OtherTest.cs
index 97562143..459fc7bf 100644
--- a/FreeSql.Tests/FreeSql.Tests/SqlServer/SqlServerExpression/OtherTest.cs
+++ b/FreeSql.Tests/FreeSql.Tests/SqlServer/SqlServerExpression/OtherTest.cs
@@ -105,9 +105,65 @@ namespace FreeSql.Tests.SqlServerExpression
var sql111111 = select.Where(a => inarray.Contains(a.testFieldInt)).ToList();
var sql112222 = select.Where(a => inarray.Contains(a.testFieldInt) == false).ToList();
var sql113333 = select.Where(a => !inarray.Contains(a.testFieldInt)).ToList();
+
+ //nvarchar
+ IEnumerable stringlinqlist = new List(new[] { "a1", "a2", "a3" });
+ var ntestlinq = select.Where(a => stringlinqlist.Contains(a.testFieldString)).ToList();
+
+ //in not in
+ var nsql111 = select.Where(a => new[] { "a1", "a2", "a3" }.Contains(a.testFieldString)).ToList();
+ var nsql112 = select.Where(a => new[] { "a1", "a2", "a3" }.Contains(a.testFieldString) == false).ToList();
+ var nsql113 = select.Where(a => !new[] { "a1", "a2", "a3" }.Contains(a.testFieldString)).ToList();
+
+ var ninarray = new[] { "a1", "a2", "a3" };
+ var nsql1111 = select.Where(a => ninarray.Contains(a.testFieldString)).ToList();
+ var nsql1122 = select.Where(a => ninarray.Contains(a.testFieldString) == false).ToList();
+ var nsql1133 = select.Where(a => !ninarray.Contains(a.testFieldString)).ToList();
+
+ //in not in
+ var nsql11111 = select.Where(a => new List() { "a1", "a2", "a3" }.Contains(a.testFieldString)).ToList();
+ var nsql11222 = select.Where(a => new List() { "a1", "a2", "a3" }.Contains(a.testFieldString) == false).ToList();
+ var nsql11333 = select.Where(a => !new List() { "a1", "a2", "a3" }.Contains(a.testFieldString)).ToList();
+
+ var nsql11111a = select.Where(a => new List(new[] { "a1", "a2", "a3" }).Contains(a.testFieldString)).ToList();
+ var nsql11222b = select.Where(a => new List(new[] { "a1", "a2", "a3" }).Contains(a.testFieldString) == false).ToList();
+ var nsql11333c = select.Where(a => !new List(new[] { "a1", "a2", "a3" }).Contains(a.testFieldString)).ToList();
+
+ var ninarray2 = new List() { "a1", "a2", "a3" };
+ var nsql111111 = select.Where(a => ninarray2.Contains(a.testFieldString)).ToList();
+ var nsql112222 = select.Where(a => ninarray2.Contains(a.testFieldString) == false).ToList();
+ var nsql113333 = select.Where(a => !ninarray2.Contains(a.testFieldString)).ToList();
+
+ //varchar
+ IEnumerable vstringlinqlist = new List(new[] { "a1", "a2", "a3" });
+ var vtestlinq = select.Where(a => vstringlinqlist.Contains(a.testFieldStringVarchar)).ToList();
+
+ //in not in
+ var vsql111 = select.Where(a => new[] { "a1", "a2", "a3" }.Contains(a.testFieldStringVarchar)).ToList();
+ var vsql112 = select.Where(a => new[] { "a1", "a2", "a3" }.Contains(a.testFieldStringVarchar) == false).ToList();
+ var vsql113 = select.Where(a => !new[] { "a1", "a2", "a3" }.Contains(a.testFieldStringVarchar)).ToList();
+
+ var vinarray = new[] { "a1", "a2", "a3" };
+ var vsql1111 = select.Where(a => ninarray.Contains(a.testFieldStringVarchar)).ToList();
+ var vsql1122 = select.Where(a => ninarray.Contains(a.testFieldStringVarchar) == false).ToList();
+ var vsql1133 = select.Where(a => !ninarray.Contains(a.testFieldStringVarchar)).ToList();
+
+ //in not in
+ var vsql11111 = select.Where(a => new List() { "a1", "a2", "a3" }.Contains(a.testFieldStringVarchar)).ToList();
+ var vsql11222 = select.Where(a => new List() { "a1", "a2", "a3" }.Contains(a.testFieldStringVarchar) == false).ToList();
+ var vsql11333 = select.Where(a => !new List() { "a1", "a2", "a3" }.Contains(a.testFieldStringVarchar)).ToList();
+
+ var vsql11111a = select.Where(a => new List(new[] { "a1", "a2", "a3" }).Contains(a.testFieldStringVarchar)).ToList();
+ var vsql11222b = select.Where(a => new List(new[] { "a1", "a2", "a3" }).Contains(a.testFieldStringVarchar) == false).ToList();
+ var vsql11333c = select.Where(a => !new List(new[] { "a1", "a2", "a3" }).Contains(a.testFieldStringVarchar)).ToList();
+
+ var vinarray2 = new List() { "a1", "a2", "a3" };
+ var vsql111111 = select.Where(a => ninarray2.Contains(a.testFieldStringVarchar)).ToList();
+ var vsql112222 = select.Where(a => ninarray2.Contains(a.testFieldStringVarchar) == false).ToList();
+ var vsql113333 = select.Where(a => !ninarray2.Contains(a.testFieldStringVarchar)).ToList();
}
- [Table(Name = "tb_alltype")]
+ [Table(Name = "tb_alltypeOther")]
class TableAllType
{
[Column(IsIdentity = true, IsPrimary = true)]
@@ -131,6 +187,9 @@ namespace FreeSql.Tests.SqlServerExpression
public DateTimeOffset testFieldDateTimeOffset { get; set; }
public byte[] testFieldBytes { get; set; }
public string testFieldString { get; set; }
+
+ [Column(DbType = "varchar(255)")]
+ public string testFieldStringVarchar { get; set; }
public Guid testFieldGuid { get; set; }
public bool? testFieldBoolNullable { get; set; }
diff --git a/FreeSql.Tests/FreeSql.Tests/SqlServer/SqlServerExpression/StringTest.cs b/FreeSql.Tests/FreeSql.Tests/SqlServer/SqlServerExpression/StringTest.cs
index c0272fa8..ecdadd3b 100644
--- a/FreeSql.Tests/FreeSql.Tests/SqlServer/SqlServerExpression/StringTest.cs
+++ b/FreeSql.Tests/FreeSql.Tests/SqlServer/SqlServerExpression/StringTest.cs
@@ -29,6 +29,8 @@ namespace FreeSql.Tests.SqlServerExpression
public int TypeGuid { get; set; }
public TestTypeInfo Type { get; set; }
public string Title { get; set; }
+ [Column(DbType = "varchar(255)")]
+ public string TitleVarchar { get; set; }
public DateTime CreateTime { get; set; }
}
class TestTypeInfo
@@ -56,7 +58,11 @@ namespace FreeSql.Tests.SqlServerExpression
{
var list = new List
+
+
+ 查询,若使用读写分离,查询【从库】条件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 b83db6ff..759aaf19 100644
--- a/FreeSql/Internal/CommonExpression.cs
+++ b/FreeSql/Internal/CommonExpression.cs
@@ -332,7 +332,7 @@ namespace FreeSql.Internal
var sql = ExpressionLambdaToSql(exp, new ExpTSC { _tables = _tables, _selectColumnMap = _selectColumnMap, getSelectGroupingMapString = getSelectGroupingMapString, tbtype = SelectTableInfoType.From, isQuoteName = true, isDisableDiyParse = false, style = ExpressionStyle.Where, currentTable = table });
var isBool = exp.Type.NullableTypeOrThis() == typeof(bool);
if (exp.NodeType == ExpressionType.MemberAccess && isBool && sql.Contains(" IS ") == false && sql.Contains(" = ") == false)
- return $"{sql} = {formatSql(true, null)}";
+ return $"{sql} = {formatSql(true, null, null)}";
if (isBool)
return GetBoolString(sql);
return sql;
@@ -343,7 +343,7 @@ namespace FreeSql.Internal
var sql = ExpressionLambdaToSql(exp, new ExpTSC { _tables = _tables, getSelectGroupingMapString = getSelectGroupingMapString, tbtype = SelectTableInfoType.From, isQuoteName = true, isDisableDiyParse = false, style = ExpressionStyle.Where, whereCascadeExpression = whereCascadeExpression });
var isBool = exp.Type.NullableTypeOrThis() == typeof(bool);
if (exp.NodeType == ExpressionType.MemberAccess && isBool && sql.Contains(" IS ") == false && sql.Contains(" = ") == false)
- return $"{sql} = {formatSql(true, null)}";
+ return $"{sql} = {formatSql(true, null, null)}";
if (isBool)
return GetBoolString(sql);
return sql;
@@ -355,7 +355,7 @@ namespace FreeSql.Internal
var sql = ExpressionLambdaToSql(exp, new ExpTSC { _tables = _tables, getSelectGroupingMapString = getSelectGroupingMapString, tbtype = tbtype, isQuoteName = true, isDisableDiyParse = false, style = ExpressionStyle.Where, whereCascadeExpression = whereCascadeExpression });
var isBool = exp.Type.NullableTypeOrThis() == typeof(bool);
if (exp.NodeType == ExpressionType.MemberAccess && isBool && sql.Contains(" IS ") == false && sql.Contains(" = ") == false)
- sql = $"{sql} = {formatSql(true, null)}";
+ sql = $"{sql} = {formatSql(true, null, null)}";
if (isBool)
sql = GetBoolString(sql);
@@ -433,7 +433,7 @@ namespace FreeSql.Internal
{
var enumType = leftMapColumn.CsType.NullableTypeOrThis();
if (enumType.IsEnum)
- right = formatSql(Enum.Parse(enumType, right.StartsWith("N'") ? right.Substring(1).Trim('\'') : right.Trim('\'')), leftMapColumn.Attribute.MapType);
+ right = formatSql(Enum.Parse(enumType, right.StartsWith("N'") ? right.Substring(1).Trim('\'') : right.Trim('\'')), leftMapColumn.Attribute.MapType, leftMapColumn);
}
if (leftMapColumn == null)
{
@@ -447,7 +447,7 @@ namespace FreeSql.Internal
{
var enumType = rightMapColumn.CsType.NullableTypeOrThis();
if (enumType.IsEnum)
- left = formatSql(Enum.Parse(enumType, left.StartsWith("N'") ? left.Substring(1).Trim('\'') : left.Trim('\'')), rightMapColumn.Attribute.MapType);
+ left = formatSql(Enum.Parse(enumType, left.StartsWith("N'") ? left.Substring(1).Trim('\'') : left.Trim('\'')), rightMapColumn.Attribute.MapType, rightMapColumn);
}
}
}
@@ -455,8 +455,8 @@ namespace FreeSql.Internal
{
if (oper == "=")
{
- var trueVal = formatSql(true, null);
- var falseVal = formatSql(false, null);
+ var trueVal = formatSql(true, null, null);
+ var falseVal = formatSql(false, null, null);
if (left == trueVal) return right;
else if (left == falseVal) return $"not({right})";
else if (right == trueVal) return left;
@@ -464,15 +464,14 @@ namespace FreeSql.Internal
}
else if (oper == "<>")
{
- var trueVal = formatSql(true, null);
- var falseVal = formatSql(false, null);
+ var trueVal = formatSql(true, null, null);
+ var falseVal = formatSql(false, null, null);
if (left == trueVal) return $"not({right})";
else if (left == falseVal) return right;
else if (right == trueVal) return $"not({left})";
else if (right == falseVal) return left;
}
}
-
if (left == "NULL")
{
var tmp = right;
@@ -488,9 +487,9 @@ namespace FreeSql.Internal
break;
case "AND":
case "OR":
- if (leftMapColumn != null) left = $"{left} = {formatSql(true, null)}";
+ if (leftMapColumn != null) left = $"{left} = {formatSql(true, null, null)}";
else left = GetBoolString(left);
- if (rightMapColumn != null) right = $"{right} = {formatSql(true, null)}";
+ if (rightMapColumn != null) right = $"{right} = {formatSql(true, null, null)}";
else right = GetBoolString(right);
break;
}
@@ -517,7 +516,7 @@ namespace FreeSql.Internal
if (notBody.Contains(" IS NOT NULL")) return notBody.Replace(" IS NOT NULL", " IS NULL");
if (notBody.Contains("=")) return notBody.Replace("=", "!=");
if (notBody.Contains("!=")) return notBody.Replace("!=", "=");
- return $"{notBody} = {formatSql(false, null)}";
+ return $"{notBody} = {formatSql(false, null, null)}";
}
return $"not({ExpressionLambdaToSql(notExp, tsc)})";
case ExpressionType.Quote: return ExpressionLambdaToSql((exp as UnaryExpression)?.Operand, tsc);
@@ -529,7 +528,7 @@ namespace FreeSql.Internal
return ExpressionLambdaToSql((exp as UnaryExpression)?.Operand, tsc);
case ExpressionType.Negate:
case ExpressionType.NegateChecked: return "-" + ExpressionLambdaToSql((exp as UnaryExpression)?.Operand, tsc);
- case ExpressionType.Constant: return formatSql((exp as ConstantExpression)?.Value, tsc.mapType);
+ case ExpressionType.Constant: return formatSql((exp as ConstantExpression)?.Value, tsc.mapType, tsc.mapColumnTmp);
case ExpressionType.Conditional:
var condExp = exp as ConditionalExpression;
return $"case when {ExpressionLambdaToSql(condExp.Test, tsc)} then {ExpressionLambdaToSql(condExp.IfTrue, tsc)} else {ExpressionLambdaToSql(condExp.IfFalse, tsc)} end";
@@ -855,7 +854,7 @@ namespace FreeSql.Internal
//}
other3Exp = ExpressionLambdaToSqlOther(exp3, tsc);
if (string.IsNullOrEmpty(other3Exp) == false) return other3Exp;
- if (exp3.IsParameter() == false) return formatSql(Expression.Lambda(exp3).Compile().DynamicInvoke(), tsc.mapType);
+ if (exp3.IsParameter() == false) return formatSql(Expression.Lambda(exp3).Compile().DynamicInvoke(), tsc.mapType, tsc.mapColumnTmp);
throw new Exception($"未实现函数表达式 {exp3} 解析");
case ExpressionType.Parameter:
case ExpressionType.MemberAccess:
@@ -915,7 +914,7 @@ namespace FreeSql.Internal
}
break;
}
- if (expStack.First().NodeType != ExpressionType.Parameter) return formatSql(Expression.Lambda(exp).Compile().DynamicInvoke(), tsc.mapType);
+ if (expStack.First().NodeType != ExpressionType.Parameter) return formatSql(Expression.Lambda(exp).Compile().DynamicInvoke(), tsc.mapType, tsc.mapColumnTmp);
if (callExp != null) return ExpressionLambdaToSql(callExp, tsc);
if (tsc.getSelectGroupingMapString != null && expStack.First().Type.FullName.StartsWith("FreeSql.ISelectGroupingAggregate`"))
{
@@ -942,7 +941,7 @@ namespace FreeSql.Internal
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;
+ tsc.SetMapColumnTmp(curcol);
if (string.IsNullOrEmpty(tsc.alias001)) return name;
return $"{tsc.alias001}.{name}";
}
@@ -1104,7 +1103,7 @@ namespace FreeSql.Internal
return "";
}
name2 = col2.Attribute.Name;
- tsc.mapTypeTmp = col2.Attribute.MapType == col2.CsType ? null : col2.Attribute.MapType;
+ tsc.SetMapColumnTmp(col2);
break;
case ExpressionType.Call: break;
}
@@ -1126,7 +1125,7 @@ namespace FreeSql.Internal
}
if (dicExpressionOperator.TryGetValue(expBinary.NodeType, out var tryoper) == false)
{
- if (exp.IsParameter() == false) return formatSql(Expression.Lambda(exp).Compile().DynamicInvoke(), tsc.mapType);
+ if (exp.IsParameter() == false) return formatSql(Expression.Lambda(exp).Compile().DynamicInvoke(), tsc.mapType, tsc.mapColumnTmp);
return "";
}
return ExpressionBinary(tryoper, expBinary.Left, expBinary.Right, tsc);
@@ -1157,13 +1156,24 @@ namespace FreeSql.Internal
public ExpressionStyle style { get; set; }
public Type mapType { get; set; }
public Type mapTypeTmp { get; set; }
+ public ColumnInfo mapColumnTmp { get; set; }
public TableInfo currentTable { get; set; }
public List whereCascadeExpression { get; set; }
public string alias001 { get; set; } //单表字段的表别名
- public void SetMapTypeTmp(Type newValue)
+ public ExpTSC SetMapColumnTmp(ColumnInfo col)
{
- this.mapTypeTmp = null;
+ if (col == null)
+ {
+ this.mapTypeTmp = null;
+ this.mapColumnTmp = null;
+ }
+ else
+ {
+ this.mapTypeTmp = col.Attribute.MapType == col.CsType ? null : col.Attribute.MapType;
+ this.mapColumnTmp = col;
+ }
+ return this;
}
public Type SetMapTypeReturnOld(Type newValue)
{
@@ -1263,6 +1273,6 @@ namespace FreeSql.Internal
}
}
- public string formatSql(object obj, Type mapType) => string.Concat(_ado.AddslashesProcessParam(obj, mapType));
+ public string formatSql(object obj, Type mapType, ColumnInfo mapColumn) => string.Concat(_ado.AddslashesProcessParam(obj, mapType, mapColumn));
}
}
diff --git a/FreeSql/Internal/CommonProvider/AdoProvider/AdoProviderUtils.cs b/FreeSql/Internal/CommonProvider/AdoProvider/AdoProviderUtils.cs
index 4d5aae64..56c43677 100644
--- a/FreeSql/Internal/CommonProvider/AdoProvider/AdoProviderUtils.cs
+++ b/FreeSql/Internal/CommonProvider/AdoProvider/AdoProviderUtils.cs
@@ -1,4 +1,5 @@
-using System;
+using FreeSql.Internal.Model;
+using System;
using System.Collections.Concurrent;
using System.Text.RegularExpressions;
@@ -6,7 +7,7 @@ namespace FreeSql.Internal.CommonProvider
{
partial class AdoProvider
{
- public abstract object AddslashesProcessParam(object param, Type mapType);
+ public abstract object AddslashesProcessParam(object param, Type mapType, ColumnInfo mapColumn);
public string Addslashes(string filter, params object[] parms)
{
if (filter == null || parms == null) return string.Empty;
@@ -17,7 +18,7 @@ namespace FreeSql.Internal.CommonProvider
if (parms[a] == null)
filter = _dicAddslashesReplaceIsNull.GetOrAdd(a, b => new Regex(@"\s*(=|IN)\s*\{" + b + @"\}", RegexOptions.IgnoreCase | RegexOptions.Compiled))
.Replace(filter, $" IS {{{a}}}");
- nparms[a] = AddslashesProcessParam(parms[a], null);
+ nparms[a] = AddslashesProcessParam(parms[a], null, null);
}
try { string ret = string.Format(filter, nparms); return ret; } catch { return filter; }
}
diff --git a/Providers/FreeSql.Provider.MySql/MySqlAdo/MySqlAdo.cs b/Providers/FreeSql.Provider.MySql/MySqlAdo/MySqlAdo.cs
index e061fe23..602ed684 100644
--- a/Providers/FreeSql.Provider.MySql/MySqlAdo/MySqlAdo.cs
+++ b/Providers/FreeSql.Provider.MySql/MySqlAdo/MySqlAdo.cs
@@ -1,4 +1,5 @@
using FreeSql.Internal;
+using FreeSql.Internal.Model;
using MySql.Data.MySqlClient;
using SafeObjectPool;
using System;
@@ -28,7 +29,7 @@ namespace FreeSql.MySql
}
}
static DateTime dt1970 = new DateTime(1970, 1, 1);
- public override object AddslashesProcessParam(object param, Type mapType)
+ public override object AddslashesProcessParam(object param, Type mapType, ColumnInfo mapColumn)
{
if (param == null) return "NULL";
if (mapType != null && mapType != param.GetType() && (param is IEnumerable == false || mapType.IsArrayOrList()))
@@ -51,7 +52,7 @@ namespace FreeSql.MySql
{
var sb = new StringBuilder();
var ie = param as IEnumerable;
- foreach (var z in ie) sb.Append(",").Append(AddslashesProcessParam(z, mapType));
+ foreach (var z in ie) sb.Append(",").Append(AddslashesProcessParam(z, mapType, mapColumn));
return sb.Length == 0 ? "(NULL)" : sb.Remove(0, 1).Insert(0, "(").Append(")").ToString();
}
return string.Concat("'", param.ToString().Replace("'", "''"), "'");
diff --git a/Providers/FreeSql.Provider.MySql/MySqlExpression.cs b/Providers/FreeSql.Provider.MySql/MySqlExpression.cs
index b795dbaf..2f3f78a8 100644
--- a/Providers/FreeSql.Provider.MySql/MySqlExpression.cs
+++ b/Providers/FreeSql.Provider.MySql/MySqlExpression.cs
@@ -101,11 +101,11 @@ namespace FreeSql.MySql
if (objType == null) objType = callExp.Method.DeclaringType;
if (objType != null || objType.IsArrayOrList())
{
- tsc?.SetMapTypeTmp(null);
+ tsc.SetMapColumnTmp(null);
var args1 = getExp(callExp.Arguments[argIndex]);
- var oldMapType = tsc?.SetMapTypeReturnOld(tsc?.mapTypeTmp);
+ var oldMapType = tsc.SetMapTypeReturnOld(tsc.mapTypeTmp);
var left = objExp == null ? null : getExp(objExp);
- tsc.SetMapTypeReturnOld(oldMapType);
+ tsc.SetMapColumnTmp(null).SetMapTypeReturnOld(oldMapType);
switch (callExp.Method.Name)
{
case "Contains":
diff --git a/Providers/FreeSql.Provider.Odbc/Default/OdbcAdapter.cs b/Providers/FreeSql.Provider.Odbc/Default/OdbcAdapter.cs
index 6eade116..ddddb518 100644
--- a/Providers/FreeSql.Provider.Odbc/Default/OdbcAdapter.cs
+++ b/Providers/FreeSql.Provider.Odbc/Default/OdbcAdapter.cs
@@ -1,4 +1,5 @@
-using System;
+using FreeSql.Internal.Model;
+using System;
using System.Collections.Generic;
using System.Text;
@@ -43,7 +44,7 @@ namespace FreeSql.Odbc.Default
public virtual char QuoteSqlNameRight => ']';
public virtual string FieldSql(Type type, string columnName) => columnName;
- public virtual string UnicodeStringRawSql(object value) => value == null ? "NULL" : string.Concat("N'", value.ToString().Replace("'", "''"), "'");
+ public virtual string UnicodeStringRawSql(object value, ColumnInfo mapColumn) => value == null ? "NULL" : string.Concat("N'", value.ToString().Replace("'", "''"), "'");
public virtual string DateTimeRawSql(object value)
{
if (value == null) return "NULL";
diff --git a/Providers/FreeSql.Provider.Odbc/Default/OdbcAdo/OdbcAdo.cs b/Providers/FreeSql.Provider.Odbc/Default/OdbcAdo/OdbcAdo.cs
index b42c5b48..2d7a2b0e 100644
--- a/Providers/FreeSql.Provider.Odbc/Default/OdbcAdo/OdbcAdo.cs
+++ b/Providers/FreeSql.Provider.Odbc/Default/OdbcAdo/OdbcAdo.cs
@@ -1,4 +1,5 @@
using FreeSql.Internal;
+using FreeSql.Internal.Model;
using SafeObjectPool;
using System;
using System.Collections;
@@ -29,7 +30,7 @@ namespace FreeSql.Odbc.Default
OdbcAdapter Adapter => (_util == null ? FreeSqlOdbcGlobalExtensions.DefaultOdbcAdapter : _util._orm.GetOdbcAdapter());
static DateTime dt1970 = new DateTime(1970, 1, 1);
- public override object AddslashesProcessParam(object param, Type mapType)
+ public override object AddslashesProcessParam(object param, Type mapType, ColumnInfo mapColumn)
{
if (param == null) return "NULL";
if (mapType != null && mapType != param.GetType() && (param is IEnumerable == false || mapType.IsArrayOrList()))
@@ -37,7 +38,7 @@ namespace FreeSql.Odbc.Default
if (param is bool || param is bool?)
return (bool)param ? 1 : 0;
else if (param is string)
- return Adapter.UnicodeStringRawSql(param);
+ return Adapter.UnicodeStringRawSql(param, mapColumn);
else if (param is char)
return string.Concat("'", param.ToString().Replace("'", "''"), "'");
else if (param is Enum)
@@ -52,7 +53,7 @@ namespace FreeSql.Odbc.Default
{
var sb = new StringBuilder();
var ie = param as IEnumerable;
- foreach (var z in ie) sb.Append(",").Append(AddslashesProcessParam(z, mapType));
+ foreach (var z in ie) sb.Append(",").Append(AddslashesProcessParam(z, mapType, mapColumn));
return sb.Length == 0 ? "(NULL)" : sb.Remove(0, 1).Insert(0, "(").Append(")").ToString();
}
return string.Concat("'", param.ToString().Replace("'", "''"), "'");
diff --git a/Providers/FreeSql.Provider.Odbc/Default/OdbcExpression.cs b/Providers/FreeSql.Provider.Odbc/Default/OdbcExpression.cs
index 574455f7..4d2bf9ea 100644
--- a/Providers/FreeSql.Provider.Odbc/Default/OdbcExpression.cs
+++ b/Providers/FreeSql.Provider.Odbc/Default/OdbcExpression.cs
@@ -108,11 +108,11 @@ namespace FreeSql.Odbc.Default
if (objType == null) objType = callExp.Method.DeclaringType;
if (objType != null || objType.IsArrayOrList())
{
- tsc?.SetMapTypeTmp(null);
+ tsc.SetMapColumnTmp(null);
var args1 = getExp(callExp.Arguments[argIndex]);
- var oldMapType = tsc?.SetMapTypeReturnOld(tsc?.mapTypeTmp);
+ var oldMapType = tsc.SetMapTypeReturnOld(tsc.mapTypeTmp);
var left = objExp == null ? null : getExp(objExp);
- tsc.SetMapTypeReturnOld(oldMapType);
+ tsc.SetMapColumnTmp(null).SetMapTypeReturnOld(oldMapType);
switch (callExp.Method.Name)
{
case "Contains":
diff --git a/Providers/FreeSql.Provider.Odbc/MySql/OdbcMySqlAdo/OdbcMySqlAdo.cs b/Providers/FreeSql.Provider.Odbc/MySql/OdbcMySqlAdo/OdbcMySqlAdo.cs
index 0cd07d54..0aa06d1a 100644
--- a/Providers/FreeSql.Provider.Odbc/MySql/OdbcMySqlAdo/OdbcMySqlAdo.cs
+++ b/Providers/FreeSql.Provider.Odbc/MySql/OdbcMySqlAdo/OdbcMySqlAdo.cs
@@ -1,4 +1,5 @@
using FreeSql.Internal;
+using FreeSql.Internal.Model;
using SafeObjectPool;
using System;
using System.Collections;
@@ -28,7 +29,7 @@ namespace FreeSql.Odbc.MySql
}
}
static DateTime dt1970 = new DateTime(1970, 1, 1);
- public override object AddslashesProcessParam(object param, Type mapType)
+ public override object AddslashesProcessParam(object param, Type mapType, ColumnInfo mapColumn)
{
if (param == null) return "NULL";
if (mapType != null && mapType != param.GetType() && (param is IEnumerable == false || mapType.IsArrayOrList()))
@@ -49,7 +50,7 @@ namespace FreeSql.Odbc.MySql
{
var sb = new StringBuilder();
var ie = param as IEnumerable;
- foreach (var z in ie) sb.Append(",").Append(AddslashesProcessParam(z, mapType));
+ foreach (var z in ie) sb.Append(",").Append(AddslashesProcessParam(z, mapType, mapColumn));
return sb.Length == 0 ? "(NULL)" : sb.Remove(0, 1).Insert(0, "(").Append(")").ToString();
}
return string.Concat("'", param.ToString().Replace("'", "''"), "'");
diff --git a/Providers/FreeSql.Provider.Odbc/MySql/OdbcMySqlExpression.cs b/Providers/FreeSql.Provider.Odbc/MySql/OdbcMySqlExpression.cs
index 2bcd91b2..14bce855 100644
--- a/Providers/FreeSql.Provider.Odbc/MySql/OdbcMySqlExpression.cs
+++ b/Providers/FreeSql.Provider.Odbc/MySql/OdbcMySqlExpression.cs
@@ -101,11 +101,11 @@ namespace FreeSql.Odbc.MySql
if (objType == null) objType = callExp.Method.DeclaringType;
if (objType != null || objType.IsArrayOrList())
{
- tsc?.SetMapTypeTmp(null);
+ tsc.SetMapColumnTmp(null);
var args1 = getExp(callExp.Arguments[argIndex]);
- var oldMapType = tsc?.SetMapTypeReturnOld(tsc?.mapTypeTmp);
+ var oldMapType = tsc.SetMapTypeReturnOld(tsc.mapTypeTmp);
var left = objExp == null ? null : getExp(objExp);
- tsc.SetMapTypeReturnOld(oldMapType);
+ tsc.SetMapColumnTmp(null).SetMapTypeReturnOld(oldMapType);
switch (callExp.Method.Name)
{
case "Contains":
diff --git a/Providers/FreeSql.Provider.Odbc/Oracle/OdbcOracleAdo/OdbcOracleAdo.cs b/Providers/FreeSql.Provider.Odbc/Oracle/OdbcOracleAdo/OdbcOracleAdo.cs
index 1bb9cfe0..6a3cd58b 100644
--- a/Providers/FreeSql.Provider.Odbc/Oracle/OdbcOracleAdo/OdbcOracleAdo.cs
+++ b/Providers/FreeSql.Provider.Odbc/Oracle/OdbcOracleAdo/OdbcOracleAdo.cs
@@ -1,4 +1,5 @@
using FreeSql.Internal;
+using FreeSql.Internal.Model;
using SafeObjectPool;
using System;
using System.Collections;
@@ -27,7 +28,7 @@ namespace FreeSql.Odbc.Oracle
}
}
static DateTime dt1970 = new DateTime(1970, 1, 1);
- public override object AddslashesProcessParam(object param, Type mapType)
+ public override object AddslashesProcessParam(object param, Type mapType, ColumnInfo mapColumn)
{
if (param == null) return "NULL";
if (mapType != null && mapType != param.GetType() && (param is IEnumerable == false || mapType.IsArrayOrList()))
@@ -48,7 +49,7 @@ namespace FreeSql.Odbc.Oracle
{
var sb = new StringBuilder();
var ie = param as IEnumerable;
- foreach (var z in ie) sb.Append(",").Append(AddslashesProcessParam(z, mapType));
+ foreach (var z in ie) sb.Append(",").Append(AddslashesProcessParam(z, mapType, mapColumn));
return sb.Length == 0 ? "(NULL)" : sb.Remove(0, 1).Insert(0, "(").Append(")").ToString();
}
return string.Concat("'", param.ToString().Replace("'", "''"), "'");
diff --git a/Providers/FreeSql.Provider.Odbc/Oracle/OdbcOracleExpression.cs b/Providers/FreeSql.Provider.Odbc/Oracle/OdbcOracleExpression.cs
index 1c9f08e4..651fbef3 100644
--- a/Providers/FreeSql.Provider.Odbc/Oracle/OdbcOracleExpression.cs
+++ b/Providers/FreeSql.Provider.Odbc/Oracle/OdbcOracleExpression.cs
@@ -101,11 +101,11 @@ namespace FreeSql.Odbc.Oracle
if (objType == null) objType = callExp.Method.DeclaringType;
if (objType != null || objType.IsArrayOrList())
{
- tsc?.SetMapTypeTmp(null);
+ tsc.SetMapColumnTmp(null);
var args1 = getExp(callExp.Arguments[argIndex]);
- var oldMapType = tsc?.SetMapTypeReturnOld(tsc?.mapTypeTmp);
+ var oldMapType = tsc.SetMapTypeReturnOld(tsc.mapTypeTmp);
var left = objExp == null ? null : getExp(objExp);
- tsc.SetMapTypeReturnOld(oldMapType);
+ tsc.SetMapColumnTmp(null).SetMapTypeReturnOld(oldMapType);
switch (callExp.Method.Name)
{
case "Contains":
diff --git a/Providers/FreeSql.Provider.Odbc/PostgreSQL/OdbcPostgreSQLAdo/OdbcPostgreSQLAdo.cs b/Providers/FreeSql.Provider.Odbc/PostgreSQL/OdbcPostgreSQLAdo/OdbcPostgreSQLAdo.cs
index 0d7027a6..862ea601 100644
--- a/Providers/FreeSql.Provider.Odbc/PostgreSQL/OdbcPostgreSQLAdo/OdbcPostgreSQLAdo.cs
+++ b/Providers/FreeSql.Provider.Odbc/PostgreSQL/OdbcPostgreSQLAdo/OdbcPostgreSQLAdo.cs
@@ -1,4 +1,5 @@
using FreeSql.Internal;
+using FreeSql.Internal.Model;
using SafeObjectPool;
using System;
using System.Collections;
@@ -29,7 +30,7 @@ namespace FreeSql.Odbc.PostgreSQL
}
static DateTime dt1970 = new DateTime(1970, 1, 1);
- public override object AddslashesProcessParam(object param, Type mapType)
+ public override object AddslashesProcessParam(object param, Type mapType, ColumnInfo mapColumn)
{
if (param == null) return "NULL";
if (mapType != null && mapType != param.GetType() && (param is IEnumerable == false || mapType.IsArrayOrList()))
@@ -50,7 +51,7 @@ namespace FreeSql.Odbc.PostgreSQL
{
var sb = new StringBuilder();
var ie = param as IEnumerable;
- foreach (var z in ie) sb.Append(",").Append(AddslashesProcessParam(z, mapType));
+ foreach (var z in ie) sb.Append(",").Append(AddslashesProcessParam(z, mapType, mapColumn));
return sb.Length == 0 ? "(NULL)" : sb.Remove(0, 1).Insert(0, "(").Append(")").ToString();
}
return string.Concat("'", param.ToString().Replace("'", "''"), "'");
diff --git a/Providers/FreeSql.Provider.Odbc/PostgreSQL/OdbcPostgreSQLExpression.cs b/Providers/FreeSql.Provider.Odbc/PostgreSQL/OdbcPostgreSQLExpression.cs
index cc7839cb..28da1107 100644
--- a/Providers/FreeSql.Provider.Odbc/PostgreSQL/OdbcPostgreSQLExpression.cs
+++ b/Providers/FreeSql.Provider.Odbc/PostgreSQL/OdbcPostgreSQLExpression.cs
@@ -130,11 +130,11 @@ namespace FreeSql.Odbc.PostgreSQL
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);
+ tsc.SetMapColumnTmp(null);
var args1 = getExp(callExp.Arguments[argIndex]);
- var oldMapType = tsc?.SetMapTypeReturnOld(tsc?.mapTypeTmp);
+ var oldMapType = tsc.SetMapTypeReturnOld(tsc.mapTypeTmp);
left = objExp == null ? null : getExp(objExp);
- tsc.SetMapTypeReturnOld(oldMapType);
+ tsc.SetMapColumnTmp(null).SetMapTypeReturnOld(oldMapType);
//判断 in 或 array @> array
if (left.StartsWith("array[") || left.EndsWith("]"))
return $"{args1} in ({left.Substring(6, left.Length - 7)})";
diff --git a/Providers/FreeSql.Provider.Odbc/SqlServer/OdbcSqlServerAdo/OdbcSqlServerAdo.cs b/Providers/FreeSql.Provider.Odbc/SqlServer/OdbcSqlServerAdo/OdbcSqlServerAdo.cs
index 3920f4b6..4ee2b561 100644
--- a/Providers/FreeSql.Provider.Odbc/SqlServer/OdbcSqlServerAdo/OdbcSqlServerAdo.cs
+++ b/Providers/FreeSql.Provider.Odbc/SqlServer/OdbcSqlServerAdo/OdbcSqlServerAdo.cs
@@ -1,9 +1,11 @@
using FreeSql.Internal;
+using FreeSql.Internal.Model;
using SafeObjectPool;
using System;
using System.Collections;
using System.Data.Common;
using System.Data.Odbc;
+using System.Linq;
using System.Text;
using System.Threading;
@@ -26,8 +28,10 @@ namespace FreeSql.Odbc.SqlServer
}
}
}
+
static DateTime dt1970 = new DateTime(1970, 1, 1);
- public override object AddslashesProcessParam(object param, Type mapType)
+ string[] ncharDbTypes = new[] { "NVARCHAR", "NCHAR", "NTEXT" };
+ public override object AddslashesProcessParam(object param, Type mapType, ColumnInfo mapColumn)
{
if (param == null) return "NULL";
if (mapType != null && mapType != param.GetType() && (param is IEnumerable == false || mapType.IsArrayOrList()))
@@ -35,7 +39,11 @@ namespace FreeSql.Odbc.SqlServer
if (param is bool || param is bool?)
return (bool)param ? 1 : 0;
else if (param is string)
+ {
+ if (mapColumn != null && mapColumn.CsType.NullableTypeOrThis() == typeof(string) && ncharDbTypes.Any(a => mapColumn.Attribute.DbType.Contains(a)) == false)
+ return string.Concat("'", param.ToString().Replace("'", "''"), "'");
return string.Concat("N'", param.ToString().Replace("'", "''"), "'");
+ }
else if (param is char)
return string.Concat("'", param.ToString().Replace("'", "''"), "'");
else if (param is Enum)
@@ -58,7 +66,7 @@ namespace FreeSql.Odbc.SqlServer
{
var sb = new StringBuilder();
var ie = param as IEnumerable;
- foreach (var z in ie) sb.Append(",").Append(AddslashesProcessParam(z, mapType));
+ foreach (var z in ie) sb.Append(",").Append(AddslashesProcessParam(z, mapType, mapColumn));
return sb.Length == 0 ? "(NULL)" : sb.Remove(0, 1).Insert(0, "(").Append(")").ToString();
}
return string.Concat("'", param.ToString().Replace("'", "''"), "'");
diff --git a/Providers/FreeSql.Provider.Odbc/SqlServer/OdbcSqlServerExpression.cs b/Providers/FreeSql.Provider.Odbc/SqlServer/OdbcSqlServerExpression.cs
index 74a752c9..7c1712bc 100644
--- a/Providers/FreeSql.Provider.Odbc/SqlServer/OdbcSqlServerExpression.cs
+++ b/Providers/FreeSql.Provider.Odbc/SqlServer/OdbcSqlServerExpression.cs
@@ -105,11 +105,11 @@ namespace FreeSql.Odbc.SqlServer
if (objType == null) objType = callExp.Method.DeclaringType;
if (objType != null || objType.IsArrayOrList())
{
- tsc?.SetMapTypeTmp(null);
+ tsc.SetMapColumnTmp(null);
var args1 = getExp(callExp.Arguments[argIndex]);
- var oldMapType = tsc?.SetMapTypeReturnOld(tsc?.mapTypeTmp);
+ var oldMapType = tsc.SetMapTypeReturnOld(tsc.mapTypeTmp);
var left = objExp == null ? null : getExp(objExp);
- tsc.SetMapTypeReturnOld(oldMapType);
+ tsc.SetMapColumnTmp(null).SetMapTypeReturnOld(oldMapType);
switch (callExp.Method.Name)
{
case "Contains":
diff --git a/Providers/FreeSql.Provider.Oracle/OracleAdo/OracleAdo.cs b/Providers/FreeSql.Provider.Oracle/OracleAdo/OracleAdo.cs
index 8c45bb19..424b8175 100644
--- a/Providers/FreeSql.Provider.Oracle/OracleAdo/OracleAdo.cs
+++ b/Providers/FreeSql.Provider.Oracle/OracleAdo/OracleAdo.cs
@@ -1,4 +1,5 @@
using FreeSql.Internal;
+using FreeSql.Internal.Model;
using Oracle.ManagedDataAccess.Client;
using SafeObjectPool;
using System;
@@ -27,7 +28,7 @@ namespace FreeSql.Oracle
}
}
static DateTime dt1970 = new DateTime(1970, 1, 1);
- public override object AddslashesProcessParam(object param, Type mapType)
+ public override object AddslashesProcessParam(object param, Type mapType, ColumnInfo mapColumn)
{
if (param == null) return "NULL";
if (mapType != null && mapType != param.GetType() && (param is IEnumerable == false || mapType.IsArrayOrList()))
@@ -48,7 +49,7 @@ namespace FreeSql.Oracle
{
var sb = new StringBuilder();
var ie = param as IEnumerable;
- foreach (var z in ie) sb.Append(",").Append(AddslashesProcessParam(z, mapType));
+ foreach (var z in ie) sb.Append(",").Append(AddslashesProcessParam(z, mapType, mapColumn));
return sb.Length == 0 ? "(NULL)" : sb.Remove(0, 1).Insert(0, "(").Append(")").ToString();
}
return string.Concat("'", param.ToString().Replace("'", "''"), "'");
diff --git a/Providers/FreeSql.Provider.Oracle/OracleExpression.cs b/Providers/FreeSql.Provider.Oracle/OracleExpression.cs
index a5f35911..818dff2b 100644
--- a/Providers/FreeSql.Provider.Oracle/OracleExpression.cs
+++ b/Providers/FreeSql.Provider.Oracle/OracleExpression.cs
@@ -101,11 +101,11 @@ namespace FreeSql.Oracle
if (objType == null) objType = callExp.Method.DeclaringType;
if (objType != null || objType.IsArrayOrList())
{
- tsc?.SetMapTypeTmp(null);
+ tsc.SetMapColumnTmp(null);
var args1 = getExp(callExp.Arguments[argIndex]);
- var oldMapType = tsc?.SetMapTypeReturnOld(tsc?.mapTypeTmp);
+ var oldMapType = tsc.SetMapTypeReturnOld(tsc.mapTypeTmp);
var left = objExp == null ? null : getExp(objExp);
- tsc.SetMapTypeReturnOld(oldMapType);
+ tsc.SetMapColumnTmp(null).SetMapTypeReturnOld(oldMapType);
switch (callExp.Method.Name)
{
case "Contains":
diff --git a/Providers/FreeSql.Provider.PostgreSQL/PostgreSQLAdo/PostgreSQLAdo.cs b/Providers/FreeSql.Provider.PostgreSQL/PostgreSQLAdo/PostgreSQLAdo.cs
index eee3e5c9..ae3c9e3f 100644
--- a/Providers/FreeSql.Provider.PostgreSQL/PostgreSQLAdo/PostgreSQLAdo.cs
+++ b/Providers/FreeSql.Provider.PostgreSQL/PostgreSQLAdo/PostgreSQLAdo.cs
@@ -1,4 +1,5 @@
using FreeSql.Internal;
+using FreeSql.Internal.Model;
using Newtonsoft.Json.Linq;
using Npgsql;
using SafeObjectPool;
@@ -30,7 +31,7 @@ namespace FreeSql.PostgreSQL
}
static DateTime dt1970 = new DateTime(1970, 1, 1);
- public override object AddslashesProcessParam(object param, Type mapType)
+ public override object AddslashesProcessParam(object param, Type mapType, ColumnInfo mapColumn)
{
if (param == null) return "NULL";
if (mapType != null && mapType != param.GetType() && (param is IEnumerable == false || mapType.IsArrayOrList() || param is JToken || param is JObject || param is JArray))
@@ -67,7 +68,7 @@ namespace FreeSql.PostgreSQL
{
var sb = new StringBuilder();
var ie = param as IEnumerable;
- foreach (var z in ie) sb.Append(",").Append(AddslashesProcessParam(z, mapType));
+ foreach (var z in ie) sb.Append(",").Append(AddslashesProcessParam(z, mapType, mapColumn));
return sb.Length == 0 ? "(NULL)" : sb.Remove(0, 1).Insert(0, "(").Append(")").ToString();
}
return string.Concat("'", param.ToString().Replace("'", "''"), "'");
diff --git a/Providers/FreeSql.Provider.PostgreSQL/PostgreSQLExpression.cs b/Providers/FreeSql.Provider.PostgreSQL/PostgreSQLExpression.cs
index 4507cebe..86760acc 100644
--- a/Providers/FreeSql.Provider.PostgreSQL/PostgreSQLExpression.cs
+++ b/Providers/FreeSql.Provider.PostgreSQL/PostgreSQLExpression.cs
@@ -160,11 +160,11 @@ namespace FreeSql.PostgreSQL
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);
+ tsc.SetMapColumnTmp(null);
var args1 = getExp(callExp.Arguments[argIndex]);
- var oldMapType = tsc?.SetMapTypeReturnOld(tsc?.mapTypeTmp);
+ var oldMapType = tsc.SetMapTypeReturnOld(tsc.mapTypeTmp);
left = objExp == null ? null : getExp(objExp);
- tsc.SetMapTypeReturnOld(oldMapType);
+ tsc.SetMapColumnTmp(null).SetMapTypeReturnOld(oldMapType);
//判断 in 或 array @> array
if (left.StartsWith("array[") || left.EndsWith("]"))
return $"{args1} in ({left.Substring(6, left.Length - 7)})";
diff --git a/Providers/FreeSql.Provider.SqlServer/SqlServerAdo/SqlServerAdo.cs b/Providers/FreeSql.Provider.SqlServer/SqlServerAdo/SqlServerAdo.cs
index c6799a13..b6e43640 100644
--- a/Providers/FreeSql.Provider.SqlServer/SqlServerAdo/SqlServerAdo.cs
+++ b/Providers/FreeSql.Provider.SqlServer/SqlServerAdo/SqlServerAdo.cs
@@ -1,9 +1,11 @@
using FreeSql.Internal;
+using FreeSql.Internal.Model;
using SafeObjectPool;
using System;
using System.Collections;
using System.Data.Common;
using System.Data.SqlClient;
+using System.Linq;
using System.Text;
using System.Threading;
@@ -26,8 +28,10 @@ namespace FreeSql.SqlServer
}
}
}
+
static DateTime dt1970 = new DateTime(1970, 1, 1);
- public override object AddslashesProcessParam(object param, Type mapType)
+ static string[] ncharDbTypes = new[] { "NVARCHAR", "NCHAR", "NTEXT" };
+ public override object AddslashesProcessParam(object param, Type mapType, ColumnInfo mapColumn)
{
if (param == null) return "NULL";
if (mapType != null && mapType != param.GetType() && (param is IEnumerable == false || mapType.IsArrayOrList()))
@@ -35,7 +39,11 @@ namespace FreeSql.SqlServer
if (param is bool || param is bool?)
return (bool)param ? 1 : 0;
else if (param is string)
+ {
+ if (mapColumn != null && mapColumn.CsType.NullableTypeOrThis() == typeof(string) && ncharDbTypes.Any(a => mapColumn.Attribute.DbType.Contains(a)) == false)
+ return string.Concat("'", param.ToString().Replace("'", "''"), "'");
return string.Concat("N'", param.ToString().Replace("'", "''"), "'");
+ }
else if (param is char)
return string.Concat("'", param.ToString().Replace("'", "''"), "'");
else if (param is Enum)
@@ -58,7 +66,7 @@ namespace FreeSql.SqlServer
{
var sb = new StringBuilder();
var ie = param as IEnumerable;
- foreach (var z in ie) sb.Append(",").Append(AddslashesProcessParam(z, mapType));
+ foreach (var z in ie) sb.Append(",").Append(AddslashesProcessParam(z, mapType, mapColumn));
return sb.Length == 0 ? "(NULL)" : sb.Remove(0, 1).Insert(0, "(").Append(")").ToString();
}
return string.Concat("'", param.ToString().Replace("'", "''"), "'");
diff --git a/Providers/FreeSql.Provider.SqlServer/SqlServerExpression.cs b/Providers/FreeSql.Provider.SqlServer/SqlServerExpression.cs
index c775851f..85edc86a 100644
--- a/Providers/FreeSql.Provider.SqlServer/SqlServerExpression.cs
+++ b/Providers/FreeSql.Provider.SqlServer/SqlServerExpression.cs
@@ -105,11 +105,11 @@ namespace FreeSql.SqlServer
if (objType == null) objType = callExp.Method.DeclaringType;
if (objType != null || objType.IsArrayOrList())
{
- tsc?.SetMapTypeTmp(null);
+ tsc.SetMapColumnTmp(null);
var args1 = getExp(callExp.Arguments[argIndex]);
- var oldMapType = tsc?.SetMapTypeReturnOld(tsc?.mapTypeTmp);
+ var oldMapType = tsc.SetMapTypeReturnOld(tsc.mapTypeTmp);
var left = objExp == null ? null : getExp(objExp);
- tsc.SetMapTypeReturnOld(oldMapType);
+ tsc.SetMapColumnTmp(null).SetMapTypeReturnOld(oldMapType);
switch (callExp.Method.Name)
{
case "Contains":
diff --git a/Providers/FreeSql.Provider.Sqlite/SqliteAdo/SqliteAdo.cs b/Providers/FreeSql.Provider.Sqlite/SqliteAdo/SqliteAdo.cs
index 9e27fc13..b8175943 100644
--- a/Providers/FreeSql.Provider.Sqlite/SqliteAdo/SqliteAdo.cs
+++ b/Providers/FreeSql.Provider.Sqlite/SqliteAdo/SqliteAdo.cs
@@ -1,4 +1,5 @@
using FreeSql.Internal;
+using FreeSql.Internal.Model;
using SafeObjectPool;
using System;
using System.Collections;
@@ -26,7 +27,7 @@ namespace FreeSql.Sqlite
}
}
static DateTime dt1970 = new DateTime(1970, 1, 1);
- public override object AddslashesProcessParam(object param, Type mapType)
+ public override object AddslashesProcessParam(object param, Type mapType, ColumnInfo mapColumn)
{
if (param == null) return "NULL";
if (mapType != null && mapType != param.GetType() && (param is IEnumerable == false || mapType.IsArrayOrList()))
@@ -47,7 +48,7 @@ namespace FreeSql.Sqlite
{
var sb = new StringBuilder();
var ie = param as IEnumerable;
- foreach (var z in ie) sb.Append(",").Append(AddslashesProcessParam(z, mapType));
+ foreach (var z in ie) sb.Append(",").Append(AddslashesProcessParam(z, mapType, mapColumn));
return sb.Length == 0 ? "(NULL)" : sb.Remove(0, 1).Insert(0, "(").Append(")").ToString();
}
return string.Concat("'", param.ToString().Replace("'", "''"), "'");
diff --git a/Providers/FreeSql.Provider.Sqlite/SqliteExpression.cs b/Providers/FreeSql.Provider.Sqlite/SqliteExpression.cs
index ce13a196..1c2f821d 100644
--- a/Providers/FreeSql.Provider.Sqlite/SqliteExpression.cs
+++ b/Providers/FreeSql.Provider.Sqlite/SqliteExpression.cs
@@ -101,11 +101,11 @@ namespace FreeSql.Sqlite
if (objType == null) objType = callExp.Method.DeclaringType;
if (objType != null || objType.IsArrayOrList())
{
- tsc?.SetMapTypeTmp(null);
+ tsc.SetMapColumnTmp(null);
var args1 = getExp(callExp.Arguments[argIndex]);
- var oldMapType = tsc?.SetMapTypeReturnOld(tsc?.mapTypeTmp);
+ var oldMapType = tsc.SetMapTypeReturnOld(tsc.mapTypeTmp);
var left = objExp == null ? null : getExp(objExp);
- tsc.SetMapTypeReturnOld(oldMapType);
+ tsc.SetMapColumnTmp(null).SetMapTypeReturnOld(oldMapType);
switch (callExp.Method.Name)
{
case "Contains":