in/not in

This commit is contained in:
28810 2018-12-29 11:53:39 +08:00
parent 43080a4052
commit 96a944c534
13 changed files with 588 additions and 225 deletions

View File

@ -1,21 +1,54 @@
# 表达式函数 # 表达式函数
| 表达式 | MySql | SqlServer | PostgreSQL | 功能说明 | | 表达式 | MySql | SqlServer | PostgreSQL | 功能说明 |
| - | - | - | - | - | | - | - | - | - | - |
| a ? b : c | case when a then b else c end | case when a then b else c end | - | a成立时取b值否则取c值 | | a ? b : c | case when athen b else c end | case when athen b else c end | case when athen b else c end | a成立时取b值否则取c值 |
| a ?? b | ifnull(a, b) | isnull(a, b) | coalesce(a, b) | 当a为null时取b值 | | a ?? b | ifnull(a, b) | isnull(a, b) | coalesce(a, b) | 当a为null时取b值 |
| 数字 + 数字 | a + b | a + b | a + b | 数字相加 | | 数字 + 数字 | a + b | a + b | a + b | 数字相加 |
| 数字 + 字符串 | concat(a, b) | cast(a as varchar) + cast(b as varchar) | case(a as varchar) \|\| b | 字符串相加a或b任意一个为字符串时 | | 数字 + 字符串 | concat(a, b) | cast(a as varchar) + cast(b as varchar) | case(a as varchar)\|\| b | 字符串相加a或b任意一个为字符串时 |
| a - b | a - b | a - b | a - b | 减 | a - b | a - b | a - b | a - b | 减
| a * b | a * b | a * b | a * b | 乘 | a * b | a * b | a * b | a * b | 乘
| a / b | a / b | a / b | a / b | 乘 | a / b | a / b | a / b | a / b | 乘
| a % b | a mod b | a mod b | a mod b | 模 | a % b | a % b | a % b | a % b | 模
> 等等... > 等等...
### 数组
| 表达式 | MySql | SqlServer | PostgreSQL | 功能说明 |
| - | - | - | - | - |
| a.Length | - | - | case when a is null then 0 else array_length(a,1) end | 数组长度 |
| 常量数组.Length | - | - | array_length(array[常量数组元素逗号分割],1) | 数组长度 |
| a.Any() | - | - | case when a is null then 0 else array_length(a,1) end > 0 | 数组是否为空 |
| 常量数组.Contains(b) | b in (常量数组元素逗号分割) | b in (常量数组元素逗号分割) | b in (常量数组元素逗号分割) | IN查询 |
| a.Contains(b) | - | - | a @> array[b] | a数组是否包含b元素 |
| a.Concat(b) | - | - | a \|\| b | 数组相连 |
| a.Count() | - | - | 同 Length | 数组长度 |
### 字典 Dictionary<string, string>
| 表达式 | MySql | SqlServer | PostgreSQL | 功能说明 |
| - | - | - | - | - |
| a.Count | - | - | case when a is null then 0 else array_length(akeys(a),1) end | 字典长度 |
| a.Keys | - | - | akeys(a) | 返回字典所有key数组 |
| a.Values | - | - | avals(a) | 返回字典所有value数组 |
| a.Contains(b) | - | - | a @> b | 字典是否包含b
| a.ContainsKey(b) | - | - | a? b | 字典是否包含key
| a.Concat(b) | - | - | a \|\| b | 字典相连 |
| a.Count() | - | - | 同 Count | 字典长度 |
### JSON JToken/JObject/JArray
| 表达式 | MySql | SqlServer | PostgreSQL | 功能说明 |
| - | - | - | - | - |
| a.Count | - | - | jsonb_array_length(coalesce(a, '[])) | json数组类型的长度 |
| a.Any() | - | - | jsonb_array_length(coalesce(a, '[])) > 0 | json数组类型是否为空 |
| a.Contains(b) | - | - | coalesce(a, '{}') @> b::jsonb | json中是否包含b |
| a.ContainsKey(b) | - | - | coalesce(a, '{}') ? b | json中是否包含键b |
| a.Concat(b) | - | - | coalesce(a, '{}') || b::jsonb | 连接两个json |
| Parse(a) | - | - | a::jsonb | 转化字符串为json类型 |
### 字符串对象 ### 字符串对象
| 表达式 | MySql | SqlServer | PostgreSQL | 功能说明 | | 表达式 | MySql | SqlServer | PostgreSQL | 功能说明 |
| - | - | - | - | - | | - | - | - | - | - |
| string.Empty | '' | '' | '' | 空字符串表示 | | string.Empty | '' | '' | '' | 空字符串表示 |
| string.IsNullOrEmpty(a) | (a is null or a = '') | (a is null or a = '') | (a is null or a = '') | 空字符串表示 |
| a.CompareTo(b) | strcmp(a, b) | - | - | 比较a和b大小 | | a.CompareTo(b) | strcmp(a, b) | - | - | 比较a和b大小 |
| a.Contains('b') | a like '%b%' | a like '%b%' | - | a是否包含b | | a.Contains('b') | a like '%b%' | a like '%b%' | - | a是否包含b |
| a.EndsWith('b') | a like '%b' | a like '%b' | - | a尾部是否包含b | | a.EndsWith('b') | a like '%b' | a like '%b' | - | a尾部是否包含b |

View File

@ -0,0 +1,92 @@
using FreeSql.DataAnnotations;
using Newtonsoft.Json.Linq;
using Npgsql;
using Npgsql.LegacyPostgis;
using NpgsqlTypes;
using System;
using System.Collections;
using System.Collections.Generic;
using System.Linq;
using System.Net;
using System.Net.NetworkInformation;
using Xunit;
namespace FreeSql.Tests.MySqlExpression {
public class OtherTest {
ISelect<TableAllType> select => g.mysql.Select<TableAllType>();
public OtherTest() {
NpgsqlConnection.GlobalTypeMapper.UseLegacyPostgis();
}
[Fact]
public void Array() {
//in not in
var sql111 = select.Where(a => new[] { 1, 2, 3 }.Contains(a.testFieldInt)).ToList();
var sql112 = select.Where(a => new[] { 1, 2, 3 }.Contains(a.testFieldInt) == false).ToList();
var sql113 = select.Where(a => !new[] { 1, 2, 3 }.Contains(a.testFieldInt)).ToList();
var inarray = new[] { 1, 2, 3 };
var sql1111 = select.Where(a => inarray.Contains(a.testFieldInt)).ToList();
var sql1122 = select.Where(a => inarray.Contains(a.testFieldInt) == false).ToList();
var sql1133 = select.Where(a => !inarray.Contains(a.testFieldInt)).ToList();
}
[Table(Name = "tb_alltype")]
class TableAllType {
[Column(IsIdentity = true, IsPrimary = true)]
public int Id { get; set; }
public bool testFieldBool { get; set; }
public sbyte testFieldSByte { get; set; }
public short testFieldShort { get; set; }
public int testFieldInt { get; set; }
public long testFieldLong { get; set; }
public byte testFieldByte { get; set; }
public ushort testFieldUShort { get; set; }
public uint testFieldUInt { get; set; }
public ulong testFieldULong { get; set; }
public double testFieldDouble { get; set; }
public float testFieldFloat { get; set; }
public decimal testFieldDecimal { get; set; }
public TimeSpan testFieldTimeSpan { get; set; }
public DateTime testFieldDateTime { get; set; }
public byte[] testFieldBytes { get; set; }
public string testFieldString { get; set; }
public Guid testFieldGuid { get; set; }
public bool? testFieldBoolNullable { get; set; }
public sbyte? testFieldSByteNullable { get; set; }
public short? testFieldShortNullable { get; set; }
public int? testFieldIntNullable { get; set; }
public long? testFielLongNullable { get; set; }
public byte? testFieldByteNullable { get; set; }
public ushort? testFieldUShortNullable { get; set; }
public uint? testFieldUIntNullable { get; set; }
public ulong? testFieldULongNullable { get; set; }
public double? testFieldDoubleNullable { get; set; }
public float? testFieldFloatNullable { get; set; }
public decimal? testFieldDecimalNullable { get; set; }
public TimeSpan? testFieldTimeSpanNullable { get; set; }
public DateTime? testFieldDateTimeNullable { get; set; }
public Guid? testFieldGuidNullable { get; set; }
public MygisPoint testFieldPoint { get; set; }
public MygisLineString testFieldLineString { get; set; }
public MygisPolygon testFieldPolygon { get; set; }
public MygisMultiPoint testFieldMultiPoint { get; set; }
public MygisMultiLineString testFieldMultiLineString { get; set; }
public MygisMultiPolygon testFieldMultiPolygon { get; set; }
public TableAllTypeEnumType1 testFieldEnum1 { get; set; }
public TableAllTypeEnumType1? testFieldEnum1Nullable { get; set; }
public TableAllTypeEnumType2 testFieldEnum2 { get; set; }
public TableAllTypeEnumType2? testFieldEnum2Nullable { get; set; }
}
public enum TableAllTypeEnumType1 { e1, e2, e3, e5 }
[Flags] public enum TableAllTypeEnumType2 { f1, f2, f3 }
}
}

View File

@ -671,5 +671,13 @@ namespace FreeSql.Tests.MySqlExpression {
//FROM `tb_topic` a, `TestTypeInfo` a__Type //FROM `tb_topic` a, `TestTypeInfo` a__Type
//WHERE (strcmp(concat(a.`Title`, 'aaa'), a__Type.`Name`) = 0) //WHERE (strcmp(concat(a.`Title`, 'aaa'), a__Type.`Name`) = 0)
} }
[Fact]
public void string_IsNullOrEmpty() {
var data = new List<object>();
data.Add(select.Where(a => string.IsNullOrEmpty(a.Title)).ToList());
data.Add(select.Where(a => string.IsNullOrEmpty(a.Title) == false).ToList());
data.Add(select.Where(a => !string.IsNullOrEmpty(a.Title)).ToList());
}
} }
} }

View File

@ -27,6 +27,16 @@ namespace FreeSql.Tests.PostgreSQLExpression {
var sql1 = select.Where(a => a.testFieldIntArray.Contains(1)).ToList(); var sql1 = select.Where(a => a.testFieldIntArray.Contains(1)).ToList();
var sql2 = select.Where(a => a.testFieldIntArray.Contains(1) == false).ToList(); var sql2 = select.Where(a => a.testFieldIntArray.Contains(1) == false).ToList();
//in not in
var sql111 = select.Where(a => new[] { 1, 2, 3 }.Contains(a.testFieldInt)).ToList();
var sql112 = select.Where(a => new[] { 1, 2, 3 }.Contains(a.testFieldInt) == false).ToList();
var sql113 = select.Where(a => !new[] { 1, 2, 3 }.Contains(a.testFieldInt)).ToList();
var inarray = new[] { 1, 2, 3 };
var sql1111 = select.Where(a => inarray.Contains(a.testFieldInt)).ToSql();
var sql1122 = select.Where(a => inarray.Contains(a.testFieldInt) == false).ToSql();
var sql1133 = select.Where(a => !inarray.Contains(a.testFieldInt)).ToSql();
var sql3 = select.Where(a => a.testFieldIntArray.Any()).ToList(); var sql3 = select.Where(a => a.testFieldIntArray.Any()).ToList();
var sql4 = select.Where(a => a.testFieldIntArray.Any() == false).ToList(); var sql4 = select.Where(a => a.testFieldIntArray.Any() == false).ToList();

View File

@ -671,5 +671,13 @@ namespace FreeSql.Tests.PostgreSQLExpression {
//FROM `tb_topic` a, `TestTypeInfo` a__Type //FROM `tb_topic` a, `TestTypeInfo` a__Type
//WHERE (strcmp(concat(a.`Title`, 'aaa'), a__Type.`Name`) = 0) //WHERE (strcmp(concat(a.`Title`, 'aaa'), a__Type.`Name`) = 0)
} }
[Fact]
public void string_IsNullOrEmpty() {
var data = new List<object>();
data.Add(select.Where(a => string.IsNullOrEmpty(a.Title)).ToList());
data.Add(select.Where(a => string.IsNullOrEmpty(a.Title) == false).ToList());
data.Add(select.Where(a => !string.IsNullOrEmpty(a.Title)).ToList());
}
} }
} }

View File

@ -0,0 +1,88 @@
using FreeSql.DataAnnotations;
using Newtonsoft.Json.Linq;
using Npgsql;
using Npgsql.LegacyPostgis;
using NpgsqlTypes;
using System;
using System.Collections;
using System.Collections.Generic;
using System.Linq;
using System.Net;
using System.Net.NetworkInformation;
using Xunit;
namespace FreeSql.Tests.SqlServerExpression {
public class OtherTest {
ISelect<TableAllType> select => g.sqlserver.Select<TableAllType>();
public OtherTest() {
NpgsqlConnection.GlobalTypeMapper.UseLegacyPostgis();
}
[Fact]
public void Array() {
//in not in
var sql111 = select.Where(a => new[] { 1, 2, 3 }.Contains(a.testFieldInt)).ToList();
//var sql112 = select.Where(a => new[] { 1, 2, 3 }.Contains(a.testFieldInt) == false).ToList();
var sql113 = select.Where(a => !new[] { 1, 2, 3 }.Contains(a.testFieldInt)).ToList();
var inarray = new[] { 1, 2, 3 };
var sql1111 = select.Where(a => inarray.Contains(a.testFieldInt)).ToList();
//var sql1122 = select.Where(a => inarray.Contains(a.testFieldInt) == false).ToList();
var sql1133 = select.Where(a => !inarray.Contains(a.testFieldInt)).ToList();
}
[Table(Name = "tb_alltype")]
class TableAllType {
[Column(IsIdentity = true, IsPrimary = true)]
public int Id { get; set; }
[Column(Name = "testFieldBool1111")]
public bool testFieldBool { get; set; }
public sbyte testFieldSByte { get; set; }
public short testFieldShort { get; set; }
public int testFieldInt { get; set; }
public long testFieldLong { get; set; }
public byte testFieldByte { get; set; }
public ushort testFieldUShort { get; set; }
public uint testFieldUInt { get; set; }
public ulong testFieldULong { get; set; }
public double testFieldDouble { get; set; }
public float testFieldFloat { get; set; }
public decimal testFieldDecimal { get; set; }
public TimeSpan testFieldTimeSpan { get; set; }
public DateTime testFieldDateTime { get; set; }
public DateTimeOffset testFieldDateTimeOffset { get; set; }
public byte[] testFieldBytes { get; set; }
public string testFieldString { get; set; }
public Guid testFieldGuid { get; set; }
public bool? testFieldBoolNullable { get; set; }
public sbyte? testFieldSByteNullable { get; set; }
public short? testFieldShortNullable { get; set; }
public int? testFieldIntNullable { get; set; }
public long? testFielLongNullable { get; set; }
public byte? testFieldByteNullable { get; set; }
public ushort? testFieldUShortNullable { get; set; }
public uint? testFieldUIntNullable { get; set; }
public ulong? testFieldULongNullable { get; set; }
public double? testFieldDoubleNullable { get; set; }
public float? testFieldFloatNullable { get; set; }
public decimal? testFieldDecimalNullable { get; set; }
public TimeSpan? testFieldTimeSpanNullable { get; set; }
public DateTime? testFieldDateTimeNullable { get; set; }
public DateTimeOffset? testFieldDateTimeNullableOffset { get; set; }
public Guid? testFieldGuidNullable { get; set; }
public TableAllTypeEnumType1 testFieldEnum1 { get; set; }
public TableAllTypeEnumType1? testFieldEnum1Nullable { get; set; }
public TableAllTypeEnumType2 testFieldEnum2 { get; set; }
public TableAllTypeEnumType2? testFieldEnum2Nullable { get; set; }
}
public enum TableAllTypeEnumType1 { e1, e2, e3, e5 }
[Flags] public enum TableAllTypeEnumType2 { f1, f2, f3 }
}
}

View File

@ -227,11 +227,19 @@ namespace FreeSql.Tests.SqlServerExpression {
//data.Add(select.Where(a => a.Title.CompareTo(a.Title) > 0).ToList()); //data.Add(select.Where(a => a.Title.CompareTo(a.Title) > 0).ToList());
//data.Add(select.Where(a => a.Title.CompareTo(a.Title + 1) == 0).ToList()); //data.Add(select.Where(a => a.Title.CompareTo(a.Title + 1) == 0).ToList());
//data.Add(select.Where(a => a.Title.CompareTo(a.Title + a.Type.Name) == 0).ToList()); //data.Add(select.Where(a => a.Title.CompareTo(a.Title + a.Type.Name) == 0).ToList());
//data.Add(select.Where(a => (a.Title + "aaa").CompareTo("aaa") == 0).ToList()); //data.Add(select.Where(a => (a.Title + "aaa").CompareTo("aaa") == 0).ToList());
//data.Add(select.Where(a => (a.Title + "aaa").CompareTo(a.Title) > 0).ToList()); //data.Add(select.Where(a => (a.Title + "aaa").CompareTo(a.Title) > 0).ToList());
//data.Add(select.Where(a => (a.Title + "aaa").CompareTo(a.Title + 1) == 0).ToList()); //data.Add(select.Where(a => (a.Title + "aaa").CompareTo(a.Title + 1) == 0).ToList());
//data.Add(select.Where(a => (a.Title + "aaa").CompareTo(a.Type.Name) == 0).ToList()); //data.Add(select.Where(a => (a.Title + "aaa").CompareTo(a.Type.Name) == 0).ToList());
} }
[Fact]
public void string_IsNullOrEmpty() {
var data = new List<object>();
data.Add(select.Where(a => string.IsNullOrEmpty(a.Title)).ToList());
//data.Add(select.Where(a => string.IsNullOrEmpty(a.Title) == false).ToList());
data.Add(select.Where(a => !string.IsNullOrEmpty(a.Title)).ToList());
}
} }
} }

View File

@ -194,6 +194,7 @@ namespace FreeSql.Internal {
internal string ExpressionLambdaToSql(Expression exp, List<SelectTableInfo> _tables, List<SelectColumnInfo> _selectColumnMap, Func<Expression[], string> getSelectGroupingMapString, SelectTableInfoType tbtype, bool isQuoteName) { internal string ExpressionLambdaToSql(Expression exp, List<SelectTableInfo> _tables, List<SelectColumnInfo> _selectColumnMap, Func<Expression[], string> getSelectGroupingMapString, SelectTableInfoType tbtype, bool isQuoteName) {
switch (exp.NodeType) { switch (exp.NodeType) {
case ExpressionType.Not: return $"not({ExpressionLambdaToSql((exp as UnaryExpression)?.Operand, _tables, _selectColumnMap, getSelectGroupingMapString, tbtype, isQuoteName)})";
case ExpressionType.Quote: return ExpressionLambdaToSql((exp as UnaryExpression)?.Operand, _tables, _selectColumnMap, getSelectGroupingMapString, tbtype, isQuoteName); case ExpressionType.Quote: return ExpressionLambdaToSql((exp as UnaryExpression)?.Operand, _tables, _selectColumnMap, getSelectGroupingMapString, tbtype, isQuoteName);
case ExpressionType.Lambda: return ExpressionLambdaToSql((exp as LambdaExpression)?.Body, _tables, _selectColumnMap, getSelectGroupingMapString, tbtype, isQuoteName); case ExpressionType.Lambda: return ExpressionLambdaToSql((exp as LambdaExpression)?.Body, _tables, _selectColumnMap, getSelectGroupingMapString, tbtype, isQuoteName);
case ExpressionType.Convert: return ExpressionLambdaToSql((exp as UnaryExpression)?.Operand, _tables, _selectColumnMap, getSelectGroupingMapString, tbtype, isQuoteName); case ExpressionType.Convert: return ExpressionLambdaToSql((exp as UnaryExpression)?.Operand, _tables, _selectColumnMap, getSelectGroupingMapString, tbtype, isQuoteName);

View File

@ -5,6 +5,7 @@ using System.Collections.Generic;
using System.Data; using System.Data;
using System.Data.Common; using System.Data.Common;
using System.Linq; using System.Linq;
using System.Text;
namespace FreeSql.Internal.CommonProvider { namespace FreeSql.Internal.CommonProvider {
abstract partial class AdoProvider : IAdo { abstract partial class AdoProvider : IAdo {
@ -30,28 +31,31 @@ namespace FreeSql.Internal.CommonProvider {
this._log = log; this._log = log;
} }
void LoggerException(ObjectPool<DbConnection> pool, DbCommand cmd, Exception e, DateTime dt, string logtxt, bool isThrowException = true) { void LoggerException(ObjectPool<DbConnection> pool, DbCommand cmd, Exception e, DateTime dt, StringBuilder logtxt, bool isThrowException = true) {
if (IsTracePerformance) { if (IsTracePerformance) {
TimeSpan ts = DateTime.Now.Subtract(dt); TimeSpan ts = DateTime.Now.Subtract(dt);
if (e == null && ts.TotalMilliseconds > 100) if (e == null && ts.TotalMilliseconds > 100)
_log.LogWarning(logtxt = $"{pool.Policy.Name}执行SQL语句耗时过长{ts.TotalMilliseconds}ms\r\n{cmd.CommandText}\r\n{logtxt}"); _log.LogWarning(logtxt.Insert(0, $"{pool.Policy.Name}执行SQL语句耗时过长{ts.TotalMilliseconds}ms\r\n{cmd.CommandText}\r\n").ToString());
else
logtxt.Insert(0, $"{pool.Policy.Name}执行SQL耗时{ts.TotalMilliseconds}ms\r\n{cmd.CommandText}\r\n").ToString();
} }
if (e == null) { if (e == null) {
AopCommandExecuted?.Invoke(cmd, logtxt); AopCommandExecuted?.Invoke(cmd, logtxt.ToString());
return; return;
} }
string log = $"{pool.Policy.Name}数据库出错执行SQL〓〓〓〓〓〓〓〓〓〓〓〓〓〓〓\r\n{cmd.CommandText}\r\n"; StringBuilder log = new StringBuilder();
log.Append(pool.Policy.Name).Append("数据库出错执行SQL〓〓〓〓〓〓〓〓〓〓〓〓〓〓〓\r\n").Append(cmd.CommandText).Append("\r\n");
foreach (DbParameter parm in cmd.Parameters) foreach (DbParameter parm in cmd.Parameters)
log += parm.ParameterName.PadRight(20, ' ') + " = " + ((parm.Value ?? DBNull.Value) == DBNull.Value ? "NULL" : parm.Value) + "\r\n"; log.Append(parm.ParameterName.PadRight(20, ' ')).Append(" = ").Append((parm.Value ?? DBNull.Value) == DBNull.Value ? "NULL" : parm.Value).Append("\r\n");
log += e.Message; log.Append(e.Message);
_log.LogError(log); _log.LogError(log.ToString());
RollbackTransaction(); RollbackTransaction();
AopCommandExecuted?.Invoke(cmd, log); AopCommandExecuted?.Invoke(cmd, log.ToString());
cmd.Parameters.Clear(); cmd.Parameters.Clear();
if (isThrowException) throw e; if (isThrowException) throw e;
@ -77,11 +81,11 @@ namespace FreeSql.Internal.CommonProvider {
} }
public void ExecuteReader(Action<DbDataReader> readerHander, string sql, object parms = null) => ExecuteReader(readerHander, CommandType.Text, sql, GetDbParamtersByObject(sql, parms)); public void ExecuteReader(Action<DbDataReader> readerHander, string sql, object parms = null) => ExecuteReader(readerHander, CommandType.Text, sql, GetDbParamtersByObject(sql, parms));
public void ExecuteReader(Action<DbDataReader> readerHander, CommandType cmdType, string cmdText, params DbParameter[] cmdParms) { public void ExecuteReader(Action<DbDataReader> readerHander, CommandType cmdType, string cmdText, params DbParameter[] cmdParms) {
DateTime dt = DateTime.Now; var dt = DateTime.Now;
string logtxt = ""; var logtxt = new StringBuilder();
DateTime logtxt_dt = DateTime.Now; var logtxt_dt = DateTime.Now;
var pool = this.MasterPool; var pool = this.MasterPool;
bool isSlave = false; var isSlave = false;
//读写分离规则 //读写分离规则
if (this.SlavePools.Any() && cmdText.StartsWith("SELECT ", StringComparison.CurrentCultureIgnoreCase)) { if (this.SlavePools.Any() && cmdText.StartsWith("SELECT ", StringComparison.CurrentCultureIgnoreCase)) {
@ -99,8 +103,8 @@ namespace FreeSql.Internal.CommonProvider {
} }
Object<DbConnection> conn = null; Object<DbConnection> conn = null;
var pc = PrepareCommand(cmdType, cmdText, cmdParms, ref logtxt); var pc = PrepareCommand(cmdType, cmdText, cmdParms, logtxt);
if (IsTracePerformance) logtxt += $"PrepareCommand: {DateTime.Now.Subtract(logtxt_dt).TotalMilliseconds}ms Total: {DateTime.Now.Subtract(dt).TotalMilliseconds}ms\r\n"; if (IsTracePerformance) logtxt.Append("PrepareCommand: ").Append(DateTime.Now.Subtract(logtxt_dt).TotalMilliseconds).Append("ms Total: ").Append(DateTime.Now.Subtract(dt).TotalMilliseconds).Append("ms\r\n");
Exception ex = null; Exception ex = null;
try { try {
if (IsTracePerformance) logtxt_dt = DateTime.Now; if (IsTracePerformance) logtxt_dt = DateTime.Now;
@ -117,7 +121,7 @@ namespace FreeSql.Internal.CommonProvider {
if (conn != null) { if (conn != null) {
if (IsTracePerformance) logtxt_dt = DateTime.Now; if (IsTracePerformance) logtxt_dt = DateTime.Now;
ReturnConnection(pool, conn, ex); //pool.Return(conn, ex); ReturnConnection(pool, conn, ex); //pool.Return(conn, ex);
if (IsTracePerformance) logtxt += $"ReleaseConnection: {DateTime.Now.Subtract(logtxt_dt).TotalMilliseconds}ms Total: {DateTime.Now.Subtract(dt).TotalMilliseconds}ms"; if (IsTracePerformance) logtxt.Append("ReleaseConnection: ").Append(DateTime.Now.Subtract(logtxt_dt).TotalMilliseconds).Append("ms Total: ").Append(DateTime.Now.Subtract(dt).TotalMilliseconds).Append("ms");
} }
LoggerException(pool, pc.cmd, new Exception($"连接失败,准备切换其他可用服务器"), dt, logtxt, false); LoggerException(pool, pc.cmd, new Exception($"连接失败,准备切换其他可用服务器"), dt, logtxt, false);
pc.cmd.Parameters.Clear(); pc.cmd.Parameters.Clear();
@ -129,15 +133,15 @@ namespace FreeSql.Internal.CommonProvider {
if (pc.cmd.Connection == null) pc.cmd.Connection = (conn = pool.Get()).Value; if (pc.cmd.Connection == null) pc.cmd.Connection = (conn = pool.Get()).Value;
} }
if (IsTracePerformance) { if (IsTracePerformance) {
logtxt += $"Open: {DateTime.Now.Subtract(logtxt_dt).TotalMilliseconds}ms Total: {DateTime.Now.Subtract(dt).TotalMilliseconds}ms\r\n"; logtxt.Append("Open: ").Append(DateTime.Now.Subtract(logtxt_dt).TotalMilliseconds).Append("ms Total: ").Append(DateTime.Now.Subtract(dt).TotalMilliseconds).Append("ms\r\n");
logtxt_dt = DateTime.Now; logtxt_dt = DateTime.Now;
} }
using (var dr = pc.cmd.ExecuteReader()) { using (var dr = pc.cmd.ExecuteReader()) {
if (IsTracePerformance) logtxt += $"ExecuteReader: {DateTime.Now.Subtract(logtxt_dt).TotalMilliseconds}ms Total: {DateTime.Now.Subtract(dt).TotalMilliseconds}ms\r\n"; if (IsTracePerformance) logtxt.Append("ExecuteReader: ").Append(DateTime.Now.Subtract(logtxt_dt).TotalMilliseconds).Append("ms Total: ").Append(DateTime.Now.Subtract(dt).TotalMilliseconds).Append("ms\r\n");
while (true) { while (true) {
if (IsTracePerformance) logtxt_dt = DateTime.Now; if (IsTracePerformance) logtxt_dt = DateTime.Now;
bool isread = dr.Read(); bool isread = dr.Read();
if (IsTracePerformance) logtxt += $" dr.Read: {DateTime.Now.Subtract(logtxt_dt).TotalMilliseconds}ms Total: {DateTime.Now.Subtract(dt).TotalMilliseconds}ms\r\n"; if (IsTracePerformance) logtxt.Append(" dr.Read: ").Append(DateTime.Now.Subtract(logtxt_dt).TotalMilliseconds).Append("ms Total: ").Append(DateTime.Now.Subtract(dt).TotalMilliseconds).Append("ms\r\n");
if (isread == false) break; if (isread == false) break;
if (readerHander != null) { if (readerHander != null) {
@ -146,17 +150,17 @@ namespace FreeSql.Internal.CommonProvider {
logtxt_dt = DateTime.Now; logtxt_dt = DateTime.Now;
values = new object[dr.FieldCount]; values = new object[dr.FieldCount];
dr.GetValues(values); dr.GetValues(values);
logtxt += $" dr.GetValues: {DateTime.Now.Subtract(logtxt_dt).TotalMilliseconds}ms Total: {DateTime.Now.Subtract(dt).TotalMilliseconds}ms\r\n"; logtxt.Append(" dr.GetValues: ").Append(DateTime.Now.Subtract(logtxt_dt).TotalMilliseconds).Append("ms Total: ").Append(DateTime.Now.Subtract(dt).TotalMilliseconds).Append("ms\r\n");
logtxt_dt = DateTime.Now; logtxt_dt = DateTime.Now;
} }
readerHander(dr); readerHander(dr);
if (IsTracePerformance) logtxt += $" readerHander: {DateTime.Now.Subtract(logtxt_dt).TotalMilliseconds}ms Total: {DateTime.Now.Subtract(dt).TotalMilliseconds}ms ({string.Join(",", values)})\r\n"; if (IsTracePerformance) logtxt.Append(" readerHander: ").Append(DateTime.Now.Subtract(logtxt_dt).TotalMilliseconds).Append("ms Total: ").Append(DateTime.Now.Subtract(dt).TotalMilliseconds).Append("ms (").Append(string.Join(", ", values)).Append(")\r\n");
} }
} }
if (IsTracePerformance) logtxt_dt = DateTime.Now; if (IsTracePerformance) logtxt_dt = DateTime.Now;
dr.Close(); dr.Close();
} }
if (IsTracePerformance) logtxt += $"ExecuteReader_dispose: {DateTime.Now.Subtract(logtxt_dt).TotalMilliseconds}ms Total: {DateTime.Now.Subtract(dt).TotalMilliseconds}ms\r\n"; if (IsTracePerformance) logtxt.Append("ExecuteReader_dispose: ").Append(DateTime.Now.Subtract(logtxt_dt).TotalMilliseconds).Append("ms Total: ").Append(DateTime.Now.Subtract(dt).TotalMilliseconds).Append("ms\r\n");
} catch (Exception ex2) { } catch (Exception ex2) {
ex = ex2; ex = ex2;
} }
@ -164,7 +168,7 @@ namespace FreeSql.Internal.CommonProvider {
if (conn != null) { if (conn != null) {
if (IsTracePerformance) logtxt_dt = DateTime.Now; if (IsTracePerformance) logtxt_dt = DateTime.Now;
ReturnConnection(pool, conn, ex); //pool.Return(conn, ex); ReturnConnection(pool, conn, ex); //pool.Return(conn, ex);
if (IsTracePerformance) logtxt += $"ReleaseConnection: {DateTime.Now.Subtract(logtxt_dt).TotalMilliseconds}ms Total: {DateTime.Now.Subtract(dt).TotalMilliseconds}ms"; if (IsTracePerformance) logtxt.Append("ReleaseConnection: ").Append(DateTime.Now.Subtract(logtxt_dt).TotalMilliseconds).Append("ms Total: ").Append(DateTime.Now.Subtract(dt).TotalMilliseconds).Append("ms");
} }
LoggerException(pool, pc.cmd, ex, dt, logtxt); LoggerException(pool, pc.cmd, ex, dt, logtxt);
pc.cmd.Parameters.Clear(); pc.cmd.Parameters.Clear();
@ -193,11 +197,11 @@ namespace FreeSql.Internal.CommonProvider {
} }
public int ExecuteNonQuery(string sql, object parms = null) => ExecuteNonQuery(CommandType.Text, sql, GetDbParamtersByObject(sql, parms)); public int ExecuteNonQuery(string sql, object parms = null) => ExecuteNonQuery(CommandType.Text, sql, GetDbParamtersByObject(sql, parms));
public int ExecuteNonQuery(CommandType cmdType, string cmdText, params DbParameter[] cmdParms) { public int ExecuteNonQuery(CommandType cmdType, string cmdText, params DbParameter[] cmdParms) {
DateTime dt = DateTime.Now; var dt = DateTime.Now;
string logtxt = ""; var logtxt = new StringBuilder();
DateTime logtxt_dt = DateTime.Now; var logtxt_dt = DateTime.Now;
Object<DbConnection> conn = null; Object<DbConnection> conn = null;
var pc = PrepareCommand(cmdType, cmdText, cmdParms, ref logtxt); var pc = PrepareCommand(cmdType, cmdText, cmdParms, logtxt);
int val = 0; int val = 0;
Exception ex = null; Exception ex = null;
try { try {
@ -210,7 +214,7 @@ namespace FreeSql.Internal.CommonProvider {
if (conn != null) { if (conn != null) {
if (IsTracePerformance) logtxt_dt = DateTime.Now; if (IsTracePerformance) logtxt_dt = DateTime.Now;
ReturnConnection(MasterPool, conn, ex); //this.MasterPool.Return(conn, ex); ReturnConnection(MasterPool, conn, ex); //this.MasterPool.Return(conn, ex);
if (IsTracePerformance) logtxt += $"ReleaseConnection: {DateTime.Now.Subtract(logtxt_dt).TotalMilliseconds}ms Total: {DateTime.Now.Subtract(dt).TotalMilliseconds}ms"; if (IsTracePerformance) logtxt.Append("ReleaseConnection: ").Append(DateTime.Now.Subtract(logtxt_dt).TotalMilliseconds).Append("ms Total: ").Append(DateTime.Now.Subtract(dt).TotalMilliseconds).Append("ms");
} }
LoggerException(this.MasterPool, pc.cmd, ex, dt, logtxt); LoggerException(this.MasterPool, pc.cmd, ex, dt, logtxt);
pc.cmd.Parameters.Clear(); pc.cmd.Parameters.Clear();
@ -218,11 +222,11 @@ namespace FreeSql.Internal.CommonProvider {
} }
public object ExecuteScalar(string sql, object parms = null) => ExecuteScalar(CommandType.Text, sql, GetDbParamtersByObject(sql, parms)); public object ExecuteScalar(string sql, object parms = null) => ExecuteScalar(CommandType.Text, sql, GetDbParamtersByObject(sql, parms));
public object ExecuteScalar(CommandType cmdType, string cmdText, params DbParameter[] cmdParms) { public object ExecuteScalar(CommandType cmdType, string cmdText, params DbParameter[] cmdParms) {
DateTime dt = DateTime.Now; var dt = DateTime.Now;
string logtxt = ""; var logtxt = new StringBuilder();
DateTime logtxt_dt = DateTime.Now; var logtxt_dt = DateTime.Now;
Object<DbConnection> conn = null; Object<DbConnection> conn = null;
var pc = PrepareCommand(cmdType, cmdText, cmdParms, ref logtxt); var pc = PrepareCommand(cmdType, cmdText, cmdParms, logtxt);
object val = null; object val = null;
Exception ex = null; Exception ex = null;
try { try {
@ -235,14 +239,14 @@ namespace FreeSql.Internal.CommonProvider {
if (conn != null) { if (conn != null) {
if (IsTracePerformance) logtxt_dt = DateTime.Now; if (IsTracePerformance) logtxt_dt = DateTime.Now;
ReturnConnection(MasterPool, conn, ex); //this.MasterPool.Return(conn, ex); ReturnConnection(MasterPool, conn, ex); //this.MasterPool.Return(conn, ex);
if (IsTracePerformance) logtxt += $"ReleaseConnection: {DateTime.Now.Subtract(logtxt_dt).TotalMilliseconds}ms Total: {DateTime.Now.Subtract(dt).TotalMilliseconds}ms"; if (IsTracePerformance) logtxt.Append("ReleaseConnection: ").Append(DateTime.Now.Subtract(logtxt_dt).TotalMilliseconds).Append("ms Total: ").Append(DateTime.Now.Subtract(dt).TotalMilliseconds).Append("ms");
} }
LoggerException(this.MasterPool, pc.cmd, ex, dt, logtxt); LoggerException(this.MasterPool, pc.cmd, ex, dt, logtxt);
pc.cmd.Parameters.Clear(); pc.cmd.Parameters.Clear();
return val; return val;
} }
private (DbTransaction tran, DbCommand cmd) PrepareCommand(CommandType cmdType, string cmdText, DbParameter[] cmdParms, ref string logtxt) { private (DbTransaction tran, DbCommand cmd) PrepareCommand(CommandType cmdType, string cmdText, DbParameter[] cmdParms, StringBuilder logtxt) {
var dt = DateTime.Now; var dt = DateTime.Now;
DbCommand cmd = CreateCommand(); DbCommand cmd = CreateCommand();
cmd.CommandType = cmdType; cmd.CommandType = cmdType;
@ -257,18 +261,18 @@ namespace FreeSql.Internal.CommonProvider {
} }
var tran = TransactionCurrentThread; var tran = TransactionCurrentThread;
if (IsTracePerformance) logtxt += $" PrepareCommand_part1: {DateTime.Now.Subtract(dt).TotalMilliseconds}ms cmdParms: {cmd.Parameters.Count}\r\n"; if (IsTracePerformance) logtxt.Append(" PrepareCommand_part1: ").Append(DateTime.Now.Subtract(dt).TotalMilliseconds).Append("ms cmdParms: ").Append(cmd.Parameters.Count).Append("\r\n");
if (tran != null) { if (tran != null) {
if (IsTracePerformance) dt = DateTime.Now; if (IsTracePerformance) dt = DateTime.Now;
cmd.Connection = tran.Connection; cmd.Connection = tran.Connection;
cmd.Transaction = tran; cmd.Transaction = tran;
if (IsTracePerformance) logtxt += $" PrepareCommand_tran!=null: {DateTime.Now.Subtract(dt).TotalMilliseconds}ms\r\n"; if (IsTracePerformance) logtxt.Append(" PrepareCommand_tran!=null: ").Append(DateTime.Now.Subtract(dt).TotalMilliseconds).Append("ms\r\n");
} }
if (IsTracePerformance) dt = DateTime.Now; if (IsTracePerformance) dt = DateTime.Now;
AutoCommitTransaction(); AutoCommitTransaction();
if (IsTracePerformance) logtxt += $" AutoCommitTransaction: {DateTime.Now.Subtract(dt).TotalMilliseconds}ms\r\n"; if (IsTracePerformance) logtxt.Append(" AutoCommitTransaction: ").Append(DateTime.Now.Subtract(dt).TotalMilliseconds).Append("ms\r\n");
AopCommandExecuting?.Invoke(cmd); AopCommandExecuting?.Invoke(cmd);
return (tran, cmd); return (tran, cmd);

View File

@ -4,6 +4,7 @@ using System.Collections.Generic;
using System.Data; using System.Data;
using System.Data.Common; using System.Data.Common;
using System.Linq; using System.Linq;
using System.Text;
using System.Threading.Tasks; using System.Threading.Tasks;
namespace FreeSql.Internal.CommonProvider { namespace FreeSql.Internal.CommonProvider {
@ -28,11 +29,11 @@ namespace FreeSql.Internal.CommonProvider {
} }
public Task ExecuteReaderAsync(Func<DbDataReader, Task> readerHander, string sql, object parms = null) => ExecuteReaderAsync(readerHander, CommandType.Text, sql, GetDbParamtersByObject(sql, parms)); public Task ExecuteReaderAsync(Func<DbDataReader, Task> readerHander, string sql, object parms = null) => ExecuteReaderAsync(readerHander, CommandType.Text, sql, GetDbParamtersByObject(sql, parms));
async public Task ExecuteReaderAsync(Func<DbDataReader, Task> readerHander, CommandType cmdType, string cmdText, params DbParameter[] cmdParms) { async public Task ExecuteReaderAsync(Func<DbDataReader, Task> readerHander, CommandType cmdType, string cmdText, params DbParameter[] cmdParms) {
DateTime dt = DateTime.Now; var dt = DateTime.Now;
string logtxt = ""; var logtxt = new StringBuilder();
DateTime logtxt_dt = DateTime.Now; var logtxt_dt = DateTime.Now;
var pool = this.MasterPool; var pool = this.MasterPool;
bool isSlave = false; var isSlave = false;
//读写分离规则 //读写分离规则
if (this.SlavePools.Any() && cmdText.StartsWith("SELECT ", StringComparison.CurrentCultureIgnoreCase)) { if (this.SlavePools.Any() && cmdText.StartsWith("SELECT ", StringComparison.CurrentCultureIgnoreCase)) {
@ -50,8 +51,8 @@ namespace FreeSql.Internal.CommonProvider {
} }
Object<DbConnection> conn = null; Object<DbConnection> conn = null;
var cmd = PrepareCommandAsync(cmdType, cmdText, cmdParms, ref logtxt); var cmd = PrepareCommandAsync(cmdType, cmdText, cmdParms, logtxt);
if (IsTracePerformance) logtxt += $"PrepareCommand: {DateTime.Now.Subtract(logtxt_dt).TotalMilliseconds}ms Total: {DateTime.Now.Subtract(dt).TotalMilliseconds}ms\r\n"; if (IsTracePerformance) logtxt.Append("PrepareCommandAsync: ").Append(DateTime.Now.Subtract(logtxt_dt).TotalMilliseconds).Append("ms Total: ").Append(DateTime.Now.Subtract(dt).TotalMilliseconds).Append("ms\r\n");
Exception ex = null; Exception ex = null;
try { try {
if (IsTracePerformance) logtxt_dt = DateTime.Now; if (IsTracePerformance) logtxt_dt = DateTime.Now;
@ -68,7 +69,7 @@ namespace FreeSql.Internal.CommonProvider {
if (conn != null) { if (conn != null) {
if (IsTracePerformance) logtxt_dt = DateTime.Now; if (IsTracePerformance) logtxt_dt = DateTime.Now;
ReturnConnection(pool, conn, ex); //pool.Return(conn, ex); ReturnConnection(pool, conn, ex); //pool.Return(conn, ex);
if (IsTracePerformance) logtxt += $"ReleaseConnection: {DateTime.Now.Subtract(logtxt_dt).TotalMilliseconds}ms Total: {DateTime.Now.Subtract(dt).TotalMilliseconds}ms"; if (IsTracePerformance) logtxt.Append("ReleaseConnection: ").Append(DateTime.Now.Subtract(logtxt_dt).TotalMilliseconds).Append("ms Total: ").Append(DateTime.Now.Subtract(dt).TotalMilliseconds).Append("ms");
} }
LoggerException(pool, cmd, new Exception($"连接失败,准备切换其他可用服务器"), dt, logtxt, false); LoggerException(pool, cmd, new Exception($"连接失败,准备切换其他可用服务器"), dt, logtxt, false);
cmd.Parameters.Clear(); cmd.Parameters.Clear();
@ -80,15 +81,15 @@ namespace FreeSql.Internal.CommonProvider {
if (cmd.Connection == null) cmd.Connection = (conn = await pool.GetAsync()).Value; if (cmd.Connection == null) cmd.Connection = (conn = await pool.GetAsync()).Value;
} }
if (IsTracePerformance) { if (IsTracePerformance) {
logtxt += $"Open: {DateTime.Now.Subtract(logtxt_dt).TotalMilliseconds}ms Total: {DateTime.Now.Subtract(dt).TotalMilliseconds}ms\r\n"; logtxt.Append("OpenAsync: ").Append(DateTime.Now.Subtract(logtxt_dt).TotalMilliseconds).Append("ms Total: ").Append(DateTime.Now.Subtract(dt).TotalMilliseconds).Append("ms\r\n");
logtxt_dt = DateTime.Now; logtxt_dt = DateTime.Now;
} }
using (var dr = await cmd.ExecuteReaderAsync()) { using (var dr = await cmd.ExecuteReaderAsync()) {
if (IsTracePerformance) logtxt += $"ExecuteReader: {DateTime.Now.Subtract(logtxt_dt).TotalMilliseconds}ms Total: {DateTime.Now.Subtract(dt).TotalMilliseconds}ms\r\n"; if (IsTracePerformance) logtxt.Append("ExecuteReaderAsync: ").Append(DateTime.Now.Subtract(logtxt_dt).TotalMilliseconds).Append("ms Total: ").Append(DateTime.Now.Subtract(dt).TotalMilliseconds).Append("ms\r\n");
while (true) { while (true) {
if (IsTracePerformance) logtxt_dt = DateTime.Now; if (IsTracePerformance) logtxt_dt = DateTime.Now;
bool isread = await dr.ReadAsync(); bool isread = await dr.ReadAsync();
if (IsTracePerformance) logtxt += $" dr.Read: {DateTime.Now.Subtract(logtxt_dt).TotalMilliseconds}ms Total: {DateTime.Now.Subtract(dt).TotalMilliseconds}ms\r\n"; if (IsTracePerformance) logtxt.Append(" dr.ReadAsync: ").Append(DateTime.Now.Subtract(logtxt_dt).TotalMilliseconds).Append("ms Total: ").Append(DateTime.Now.Subtract(dt).TotalMilliseconds).Append("ms\r\n");
if (isread == false) break; if (isread == false) break;
if (readerHander != null) { if (readerHander != null) {
@ -97,17 +98,17 @@ namespace FreeSql.Internal.CommonProvider {
logtxt_dt = DateTime.Now; logtxt_dt = DateTime.Now;
values = new object[dr.FieldCount]; values = new object[dr.FieldCount];
for (int a = 0; a < values.Length; a++) if (!await dr.IsDBNullAsync(a)) values[a] = await dr.GetFieldValueAsync<object>(a); for (int a = 0; a < values.Length; a++) if (!await dr.IsDBNullAsync(a)) values[a] = await dr.GetFieldValueAsync<object>(a);
logtxt += $" dr.GetValues: {DateTime.Now.Subtract(logtxt_dt).TotalMilliseconds}ms Total: {DateTime.Now.Subtract(dt).TotalMilliseconds}ms\r\n"; logtxt.Append(" dr.GetValues: ").Append(DateTime.Now.Subtract(logtxt_dt).TotalMilliseconds).Append("ms Total: ").Append(DateTime.Now.Subtract(dt).TotalMilliseconds).Append("ms\r\n");
logtxt_dt = DateTime.Now; logtxt_dt = DateTime.Now;
} }
await readerHander(dr); await readerHander(dr);
if (IsTracePerformance) logtxt += $" readerHander: {DateTime.Now.Subtract(logtxt_dt).TotalMilliseconds}ms Total: {DateTime.Now.Subtract(dt).TotalMilliseconds}ms ({string.Join(",", values)})\r\n"; if (IsTracePerformance) logtxt.Append(" readerHanderAsync: ").Append(DateTime.Now.Subtract(logtxt_dt).TotalMilliseconds).Append("ms Total: ").Append(DateTime.Now.Subtract(dt).TotalMilliseconds).Append("ms (").Append(string.Join(", ", values)).Append(")\r\n");
} }
} }
if (IsTracePerformance) logtxt_dt = DateTime.Now; if (IsTracePerformance) logtxt_dt = DateTime.Now;
dr.Close(); dr.Close();
} }
if (IsTracePerformance) logtxt += $"ExecuteReader_dispose: {DateTime.Now.Subtract(logtxt_dt).TotalMilliseconds}ms Total: {DateTime.Now.Subtract(dt).TotalMilliseconds}ms\r\n"; if (IsTracePerformance) logtxt.Append("ExecuteReaderAsync_dispose: ").Append(DateTime.Now.Subtract(logtxt_dt).TotalMilliseconds).Append("ms Total: ").Append(DateTime.Now.Subtract(dt).TotalMilliseconds).Append("ms\r\n");
} catch (Exception ex2) { } catch (Exception ex2) {
ex = ex2; ex = ex2;
} }
@ -115,7 +116,7 @@ namespace FreeSql.Internal.CommonProvider {
if (conn != null) { if (conn != null) {
if (IsTracePerformance) logtxt_dt = DateTime.Now; if (IsTracePerformance) logtxt_dt = DateTime.Now;
ReturnConnection(pool, conn, ex); //pool.Return(conn, ex); ReturnConnection(pool, conn, ex); //pool.Return(conn, ex);
if (IsTracePerformance) logtxt += $"ReleaseConnection: {DateTime.Now.Subtract(logtxt_dt).TotalMilliseconds}ms Total: {DateTime.Now.Subtract(dt).TotalMilliseconds}ms"; if (IsTracePerformance) logtxt.Append("ReleaseConnection: ").Append(DateTime.Now.Subtract(logtxt_dt).TotalMilliseconds).Append("ms Total: ").Append(DateTime.Now.Subtract(dt).TotalMilliseconds).Append("ms");
} }
LoggerException(pool, cmd, ex, dt, logtxt); LoggerException(pool, cmd, ex, dt, logtxt);
cmd.Parameters.Clear(); cmd.Parameters.Clear();
@ -144,11 +145,11 @@ namespace FreeSql.Internal.CommonProvider {
} }
public Task<int> ExecuteNonQueryAsync(string sql, object parms = null) => ExecuteNonQueryAsync(CommandType.Text, sql, GetDbParamtersByObject(sql, parms)); public Task<int> ExecuteNonQueryAsync(string sql, object parms = null) => ExecuteNonQueryAsync(CommandType.Text, sql, GetDbParamtersByObject(sql, parms));
async public Task<int> ExecuteNonQueryAsync(CommandType cmdType, string cmdText, params DbParameter[] cmdParms) { async public Task<int> ExecuteNonQueryAsync(CommandType cmdType, string cmdText, params DbParameter[] cmdParms) {
DateTime dt = DateTime.Now; var dt = DateTime.Now;
string logtxt = ""; var logtxt = new StringBuilder();
Object<DbConnection> conn = null;
var cmd = PrepareCommandAsync(cmdType, cmdText, cmdParms, ref logtxt);
var logtxt_dt = DateTime.Now; var logtxt_dt = DateTime.Now;
Object<DbConnection> conn = null;
var cmd = PrepareCommandAsync(cmdType, cmdText, cmdParms, logtxt);
int val = 0; int val = 0;
Exception ex = null; Exception ex = null;
try { try {
@ -161,7 +162,7 @@ namespace FreeSql.Internal.CommonProvider {
if (conn != null) { if (conn != null) {
if (IsTracePerformance) logtxt_dt = DateTime.Now; if (IsTracePerformance) logtxt_dt = DateTime.Now;
ReturnConnection(MasterPool, conn, ex); //this.MasterPool.Return(conn, ex); ReturnConnection(MasterPool, conn, ex); //this.MasterPool.Return(conn, ex);
if (IsTracePerformance) logtxt += $"ReleaseConnection: {DateTime.Now.Subtract(logtxt_dt).TotalMilliseconds}ms Total: {DateTime.Now.Subtract(dt).TotalMilliseconds}ms"; if (IsTracePerformance) logtxt.Append("ReleaseConnection: ").Append(DateTime.Now.Subtract(logtxt_dt).TotalMilliseconds).Append("ms Total: ").Append(DateTime.Now.Subtract(dt).TotalMilliseconds).Append("ms");
} }
LoggerException(this.MasterPool, cmd, ex, dt, logtxt); LoggerException(this.MasterPool, cmd, ex, dt, logtxt);
cmd.Parameters.Clear(); cmd.Parameters.Clear();
@ -170,10 +171,10 @@ namespace FreeSql.Internal.CommonProvider {
public Task<object> ExecuteScalarAsync(string sql, object parms = null) => ExecuteScalarAsync(CommandType.Text, sql, GetDbParamtersByObject(sql, parms)); public Task<object> ExecuteScalarAsync(string sql, object parms = null) => ExecuteScalarAsync(CommandType.Text, sql, GetDbParamtersByObject(sql, parms));
async public Task<object> ExecuteScalarAsync(CommandType cmdType, string cmdText, params DbParameter[] cmdParms) { async public Task<object> ExecuteScalarAsync(CommandType cmdType, string cmdText, params DbParameter[] cmdParms) {
var dt = DateTime.Now; var dt = DateTime.Now;
var logtxt = ""; var logtxt = new StringBuilder();
Object<DbConnection> conn = null;
var cmd = PrepareCommandAsync(cmdType, cmdText, cmdParms, ref logtxt);
var logtxt_dt = DateTime.Now; var logtxt_dt = DateTime.Now;
Object<DbConnection> conn = null;
var cmd = PrepareCommandAsync(cmdType, cmdText, cmdParms, logtxt);
object val = null; object val = null;
Exception ex = null; Exception ex = null;
try { try {
@ -186,14 +187,14 @@ namespace FreeSql.Internal.CommonProvider {
if (conn != null) { if (conn != null) {
if (IsTracePerformance) logtxt_dt = DateTime.Now; if (IsTracePerformance) logtxt_dt = DateTime.Now;
ReturnConnection(MasterPool, conn, ex); //this.MasterPool.Return(conn, ex); ReturnConnection(MasterPool, conn, ex); //this.MasterPool.Return(conn, ex);
if (IsTracePerformance) logtxt += $"ReleaseConnection: {DateTime.Now.Subtract(logtxt_dt).TotalMilliseconds}ms Total: {DateTime.Now.Subtract(dt).TotalMilliseconds}ms"; if (IsTracePerformance) logtxt.Append("ReleaseConnection: ").Append(DateTime.Now.Subtract(logtxt_dt).TotalMilliseconds).Append("ms Total: ").Append(DateTime.Now.Subtract(dt).TotalMilliseconds).Append("ms");
} }
LoggerException(this.MasterPool, cmd, ex, dt, logtxt); LoggerException(this.MasterPool, cmd, ex, dt, logtxt);
cmd.Parameters.Clear(); cmd.Parameters.Clear();
return val; return val;
} }
private DbCommand PrepareCommandAsync(CommandType cmdType, string cmdText, DbParameter[] cmdParms, ref string logtxt) { private DbCommand PrepareCommandAsync(CommandType cmdType, string cmdText, DbParameter[] cmdParms, StringBuilder logtxt) {
DateTime dt = DateTime.Now; DateTime dt = DateTime.Now;
DbCommand cmd = CreateCommand(); DbCommand cmd = CreateCommand();
cmd.CommandType = cmdType; cmd.CommandType = cmdType;
@ -207,7 +208,7 @@ namespace FreeSql.Internal.CommonProvider {
} }
} }
if (IsTracePerformance) logtxt += $" PrepareCommand_tran==null: {DateTime.Now.Subtract(dt).TotalMilliseconds}ms cmdParms: {cmd.Parameters.Count}\r\n"; if (IsTracePerformance) logtxt.Append(" PrepareCommand_tran==null: ").Append(DateTime.Now.Subtract(dt).TotalMilliseconds).Append("ms cmdParms: ").Append(cmd.Parameters.Count).Append("\r\n");
AopCommandExecuting?.Invoke(cmd); AopCommandExecuting?.Invoke(cmd);
return cmd; return cmd;

View File

@ -4,6 +4,7 @@ using System;
using System.Collections.Generic; using System.Collections.Generic;
using System.Linq; using System.Linq;
using System.Linq.Expressions; using System.Linq.Expressions;
using System.Text;
namespace FreeSql.MySql { namespace FreeSql.MySql {
class MySqlExpression : CommonExpression { class MySqlExpression : CommonExpression {
@ -11,6 +12,41 @@ namespace FreeSql.MySql {
public MySqlExpression(CommonUtils common) : base(common) { } public MySqlExpression(CommonUtils common) : base(common) { }
internal override string ExpressionLambdaToSqlOther(Expression exp, List<SelectTableInfo> _tables, List<SelectColumnInfo> _selectColumnMap, Func<Expression[], string> getSelectGroupingMapString, SelectTableInfoType tbtype, bool isQuoteName) { internal override string ExpressionLambdaToSqlOther(Expression exp, List<SelectTableInfo> _tables, List<SelectColumnInfo> _selectColumnMap, Func<Expression[], string> getSelectGroupingMapString, SelectTableInfoType tbtype, bool isQuoteName) {
switch (exp.NodeType) {
case ExpressionType.Call:
var callExp = exp as MethodCallExpression;
var objExp = callExp.Object;
var objType = objExp?.Type;
if (objType?.FullName == "System.Byte[]") return null;
var argIndex = 0;
if (objType == null && callExp.Method.DeclaringType.FullName == typeof(Enumerable).FullName) {
objExp = callExp.Arguments.FirstOrDefault();
objType = objExp?.Type;
argIndex++;
}
if (objType == null) objType = callExp.Method.DeclaringType;
if (objType != null) {
var left = objExp == null ? null : ExpressionLambdaToSql(objExp, _tables, _selectColumnMap, getSelectGroupingMapString, tbtype, isQuoteName);
if (objType.IsArray == true) {
switch (callExp.Method.Name) {
case "Contains":
//判断 in
return $"({ExpressionLambdaToSql(callExp.Arguments[argIndex], _tables, _selectColumnMap, getSelectGroupingMapString, tbtype, isQuoteName)}) in {left}";
}
}
}
break;
case ExpressionType.NewArrayInit:
var arrExp = exp as NewArrayExpression;
var arrSb = new StringBuilder();
arrSb.Append("(");
for (var a = 0; a < arrExp.Expressions.Count; a++) {
if (a > 0) arrSb.Append(",");
arrSb.Append(ExpressionLambdaToSql(arrExp.Expressions[a], _tables, _selectColumnMap, getSelectGroupingMapString, tbtype, isQuoteName));
}
return arrSb.Append(")").ToString();
}
return null; return null;
} }
@ -82,64 +118,72 @@ namespace FreeSql.MySql {
} }
internal override string ExpressionLambdaToSqlCallString(MethodCallExpression exp, List<SelectTableInfo> _tables, List<SelectColumnInfo> _selectColumnMap, Func<Expression[], string> getSelectGroupingMapString, SelectTableInfoType tbtype, bool isQuoteName) { internal override string ExpressionLambdaToSqlCallString(MethodCallExpression exp, List<SelectTableInfo> _tables, List<SelectColumnInfo> _selectColumnMap, Func<Expression[], string> getSelectGroupingMapString, SelectTableInfoType tbtype, bool isQuoteName) {
var left = ExpressionLambdaToSql(exp.Object, _tables, _selectColumnMap, getSelectGroupingMapString, tbtype, isQuoteName); if (exp.Object == null) {
switch (exp.Method.Name) { switch (exp.Method.Name) {
case "StartsWith": case "IsNullOrEmpty":
case "EndsWith": var arg1 = ExpressionLambdaToSql(exp.Arguments[0], _tables, _selectColumnMap, getSelectGroupingMapString, tbtype, isQuoteName);
case "Contains": return $"({arg1} is null or {arg1} = '')";
var args0Value = ExpressionLambdaToSql(exp.Arguments[0], _tables, _selectColumnMap, getSelectGroupingMapString, tbtype, isQuoteName); }
if (args0Value == "NULL") return $"({left}) IS NULL"; } else {
if (exp.Method.Name == "StartsWith") return $"({left}) LIKE {(args0Value.EndsWith("'") ? args0Value.Insert(args0Value.Length - 1, "%") : $"concat({args0Value}, '%')")}"; var left = ExpressionLambdaToSql(exp.Object, _tables, _selectColumnMap, getSelectGroupingMapString, tbtype, isQuoteName);
if (exp.Method.Name == "EndsWith") return $"({left}) LIKE {(args0Value.StartsWith("'") ? args0Value.Insert(1, "%") : $"concat('%', {args0Value})")}"; switch (exp.Method.Name) {
if (args0Value.StartsWith("'") && args0Value.EndsWith("'")) return $"({left}) LIKE {args0Value.Insert(1, "%").Insert(args0Value.Length, "%")}"; case "StartsWith":
return $"({left}) LIKE concat('%', {args0Value}, '%')"; case "EndsWith":
case "ToLower": return $"lower({left})"; case "Contains":
case "ToUpper": return $"upper({left})"; var args0Value = ExpressionLambdaToSql(exp.Arguments[0], _tables, _selectColumnMap, getSelectGroupingMapString, tbtype, isQuoteName);
case "Substring": if (args0Value == "NULL") return $"({left}) IS NULL";
var substrArgs1 = ExpressionLambdaToSql(exp.Arguments[0], _tables, _selectColumnMap, getSelectGroupingMapString, tbtype, isQuoteName); if (exp.Method.Name == "StartsWith") return $"({left}) LIKE {(args0Value.EndsWith("'") ? args0Value.Insert(args0Value.Length - 1, "%") : $"concat({args0Value}, '%')")}";
if (long.TryParse(substrArgs1, out var testtrylng1)) substrArgs1 = (testtrylng1 + 1).ToString(); if (exp.Method.Name == "EndsWith") return $"({left}) LIKE {(args0Value.StartsWith("'") ? args0Value.Insert(1, "%") : $"concat('%', {args0Value})")}";
else substrArgs1 += "+1"; if (args0Value.StartsWith("'") && args0Value.EndsWith("'")) return $"({left}) LIKE {args0Value.Insert(1, "%").Insert(args0Value.Length, "%")}";
if (exp.Arguments.Count == 1) return $"substr({left}, {substrArgs1})"; return $"({left}) LIKE concat('%', {args0Value}, '%')";
return $"substr({left}, {substrArgs1}, {ExpressionLambdaToSql(exp.Arguments[1], _tables, _selectColumnMap, getSelectGroupingMapString, tbtype, isQuoteName)})"; case "ToLower": return $"lower({left})";
case "IndexOf": case "ToUpper": return $"upper({left})";
var indexOfFindStr = ExpressionLambdaToSql(exp.Arguments[0], _tables, _selectColumnMap, getSelectGroupingMapString, tbtype, isQuoteName); case "Substring":
if (exp.Arguments.Count > 1 && exp.Arguments[1].Type.FullName == "System.Int32") { var substrArgs1 = ExpressionLambdaToSql(exp.Arguments[0], _tables, _selectColumnMap, getSelectGroupingMapString, tbtype, isQuoteName);
var locateArgs1 = ExpressionLambdaToSql(exp.Arguments[1], _tables, _selectColumnMap, getSelectGroupingMapString, tbtype, isQuoteName); if (long.TryParse(substrArgs1, out var testtrylng1)) substrArgs1 = (testtrylng1 + 1).ToString();
if (long.TryParse(locateArgs1, out var testtrylng2)) locateArgs1 = (testtrylng2 + 1).ToString(); else substrArgs1 += "+1";
else locateArgs1 += "+1"; if (exp.Arguments.Count == 1) return $"substr({left}, {substrArgs1})";
return $"(locate({left}, {indexOfFindStr}, {locateArgs1})-1)"; return $"substr({left}, {substrArgs1}, {ExpressionLambdaToSql(exp.Arguments[1], _tables, _selectColumnMap, getSelectGroupingMapString, tbtype, isQuoteName)})";
} case "IndexOf":
return $"(locate({left}, {indexOfFindStr})-1)"; var indexOfFindStr = ExpressionLambdaToSql(exp.Arguments[0], _tables, _selectColumnMap, getSelectGroupingMapString, tbtype, isQuoteName);
case "PadLeft": if (exp.Arguments.Count > 1 && exp.Arguments[1].Type.FullName == "System.Int32") {
if (exp.Arguments.Count == 1) return $"lpad({left}, {ExpressionLambdaToSql(exp.Arguments[0], _tables, _selectColumnMap, getSelectGroupingMapString, tbtype, isQuoteName)})"; var locateArgs1 = ExpressionLambdaToSql(exp.Arguments[1], _tables, _selectColumnMap, getSelectGroupingMapString, tbtype, isQuoteName);
return $"lpad({left}, {ExpressionLambdaToSql(exp.Arguments[0], _tables, _selectColumnMap, getSelectGroupingMapString, tbtype, isQuoteName)}, {ExpressionLambdaToSql(exp.Arguments[1], _tables, _selectColumnMap, getSelectGroupingMapString, tbtype, isQuoteName)})"; if (long.TryParse(locateArgs1, out var testtrylng2)) locateArgs1 = (testtrylng2 + 1).ToString();
case "PadRight": else locateArgs1 += "+1";
if (exp.Arguments.Count == 1) return $"rpad({left}, {ExpressionLambdaToSql(exp.Arguments[0], _tables, _selectColumnMap, getSelectGroupingMapString, tbtype, isQuoteName)})"; return $"(locate({left}, {indexOfFindStr}, {locateArgs1})-1)";
return $"rpad({left}, {ExpressionLambdaToSql(exp.Arguments[0], _tables, _selectColumnMap, getSelectGroupingMapString, tbtype, isQuoteName)}, {ExpressionLambdaToSql(exp.Arguments[1], _tables, _selectColumnMap, getSelectGroupingMapString, tbtype, isQuoteName)})";
case "Trim":
case "TrimStart":
case "TrimEnd":
if (exp.Arguments.Count == 0) {
if (exp.Method.Name == "Trim") return $"trim({left})";
if (exp.Method.Name == "TrimStart") return $"ltrim({left})";
if (exp.Method.Name == "TrimEnd") return $"rtrim({left})";
}
foreach (var argsTrim02 in exp.Arguments) {
var argsTrim01s = new[] { argsTrim02 };
if (argsTrim02.NodeType == ExpressionType.NewArrayInit) {
var arritem = argsTrim02 as NewArrayExpression;
argsTrim01s = arritem.Expressions.ToArray();
} }
foreach (var argsTrim01 in argsTrim01s) { return $"(locate({left}, {indexOfFindStr})-1)";
if (exp.Method.Name == "Trim") left = $"trim({ExpressionLambdaToSql(argsTrim01, _tables, _selectColumnMap, getSelectGroupingMapString, tbtype, isQuoteName)} from {left})"; case "PadLeft":
if (exp.Method.Name == "TrimStart") left = $"trim(leading {ExpressionLambdaToSql(argsTrim01, _tables, _selectColumnMap, getSelectGroupingMapString, tbtype, isQuoteName)} from {left})"; if (exp.Arguments.Count == 1) return $"lpad({left}, {ExpressionLambdaToSql(exp.Arguments[0], _tables, _selectColumnMap, getSelectGroupingMapString, tbtype, isQuoteName)})";
if (exp.Method.Name == "TrimEnd") left = $"trim(trailing {ExpressionLambdaToSql(argsTrim01, _tables, _selectColumnMap, getSelectGroupingMapString, tbtype, isQuoteName)} from {left})"; return $"lpad({left}, {ExpressionLambdaToSql(exp.Arguments[0], _tables, _selectColumnMap, getSelectGroupingMapString, tbtype, isQuoteName)}, {ExpressionLambdaToSql(exp.Arguments[1], _tables, _selectColumnMap, getSelectGroupingMapString, tbtype, isQuoteName)})";
case "PadRight":
if (exp.Arguments.Count == 1) return $"rpad({left}, {ExpressionLambdaToSql(exp.Arguments[0], _tables, _selectColumnMap, getSelectGroupingMapString, tbtype, isQuoteName)})";
return $"rpad({left}, {ExpressionLambdaToSql(exp.Arguments[0], _tables, _selectColumnMap, getSelectGroupingMapString, tbtype, isQuoteName)}, {ExpressionLambdaToSql(exp.Arguments[1], _tables, _selectColumnMap, getSelectGroupingMapString, tbtype, isQuoteName)})";
case "Trim":
case "TrimStart":
case "TrimEnd":
if (exp.Arguments.Count == 0) {
if (exp.Method.Name == "Trim") return $"trim({left})";
if (exp.Method.Name == "TrimStart") return $"ltrim({left})";
if (exp.Method.Name == "TrimEnd") return $"rtrim({left})";
} }
} foreach (var argsTrim02 in exp.Arguments) {
return left; var argsTrim01s = new[] { argsTrim02 };
case "Replace": return $"replace({left}, {ExpressionLambdaToSql(exp.Arguments[0], _tables, _selectColumnMap, getSelectGroupingMapString, tbtype, isQuoteName)}, {ExpressionLambdaToSql(exp.Arguments[1], _tables, _selectColumnMap, getSelectGroupingMapString, tbtype, isQuoteName)})"; if (argsTrim02.NodeType == ExpressionType.NewArrayInit) {
case "CompareTo": return $"strcmp({left}, {ExpressionLambdaToSql(exp.Arguments[0], _tables, _selectColumnMap, getSelectGroupingMapString, tbtype, isQuoteName)})"; var arritem = argsTrim02 as NewArrayExpression;
case "Equals": return $"({left} = {ExpressionLambdaToSql(exp.Arguments[0], _tables, _selectColumnMap, getSelectGroupingMapString, tbtype, isQuoteName)})"; argsTrim01s = arritem.Expressions.ToArray();
}
foreach (var argsTrim01 in argsTrim01s) {
if (exp.Method.Name == "Trim") left = $"trim({ExpressionLambdaToSql(argsTrim01, _tables, _selectColumnMap, getSelectGroupingMapString, tbtype, isQuoteName)} from {left})";
if (exp.Method.Name == "TrimStart") left = $"trim(leading {ExpressionLambdaToSql(argsTrim01, _tables, _selectColumnMap, getSelectGroupingMapString, tbtype, isQuoteName)} from {left})";
if (exp.Method.Name == "TrimEnd") left = $"trim(trailing {ExpressionLambdaToSql(argsTrim01, _tables, _selectColumnMap, getSelectGroupingMapString, tbtype, isQuoteName)} from {left})";
}
}
return left;
case "Replace": return $"replace({left}, {ExpressionLambdaToSql(exp.Arguments[0], _tables, _selectColumnMap, getSelectGroupingMapString, tbtype, isQuoteName)}, {ExpressionLambdaToSql(exp.Arguments[1], _tables, _selectColumnMap, getSelectGroupingMapString, tbtype, isQuoteName)})";
case "CompareTo": return $"strcmp({left}, {ExpressionLambdaToSql(exp.Arguments[0], _tables, _selectColumnMap, getSelectGroupingMapString, tbtype, isQuoteName)})";
case "Equals": return $"({left} = {ExpressionLambdaToSql(exp.Arguments[0], _tables, _selectColumnMap, getSelectGroupingMapString, tbtype, isQuoteName)})";
}
} }
throw new Exception($"MySqlExpression 未现实函数表达式 {exp} 解析"); throw new Exception($"MySqlExpression 未现实函数表达式 {exp} 解析");
} }

View File

@ -16,7 +16,7 @@ namespace FreeSql.PostgreSQL {
switch (exp.NodeType) { switch (exp.NodeType) {
case ExpressionType.ArrayLength: case ExpressionType.ArrayLength:
var arrOperExp = ExpressionLambdaToSql((exp as UnaryExpression).Operand, _tables, _selectColumnMap, getSelectGroupingMapString, tbtype, isQuoteName); var arrOperExp = ExpressionLambdaToSql((exp as UnaryExpression).Operand, _tables, _selectColumnMap, getSelectGroupingMapString, tbtype, isQuoteName);
if (arrOperExp.StartsWith("(") || arrOperExp.EndsWith(")")) return $"array_length(array[{arrOperExp.TrimStart('(').TrimEnd(')')}])"; if (arrOperExp.StartsWith("(") || arrOperExp.EndsWith(")")) return $"array_length(array[{arrOperExp.TrimStart('(').TrimEnd(')')}],1)";
return $"case when {arrOperExp} is null then 0 else array_length({arrOperExp},1) end"; return $"case when {arrOperExp} is null then 0 else array_length({arrOperExp},1) end";
case ExpressionType.Call: case ExpressionType.Call:
var callExp = exp as MethodCallExpression; var callExp = exp as MethodCallExpression;
@ -34,18 +34,30 @@ namespace FreeSql.PostgreSQL {
if (objType != null) { if (objType != null) {
var left = objExp == null ? null : ExpressionLambdaToSql(objExp, _tables, _selectColumnMap, getSelectGroupingMapString, tbtype, isQuoteName); var left = objExp == null ? null : ExpressionLambdaToSql(objExp, _tables, _selectColumnMap, getSelectGroupingMapString, tbtype, isQuoteName);
if (objType.IsArray == true) { if (objType.IsArray == true) {
if (left.StartsWith("(") || left.EndsWith(")")) left = $"array[{left.TrimStart('(').TrimEnd(')')}]";
switch (callExp.Method.Name) { switch (callExp.Method.Name) {
case "Any": return $"(case when {left} is null then 0 else array_length({left},1) end > 0)"; case "Any":
case "Contains": return $"({left} @> array[{ExpressionLambdaToSql(callExp.Arguments[argIndex], _tables, _selectColumnMap, getSelectGroupingMapString, tbtype, isQuoteName)}])"; 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":
//判断 in 或 array @> array
var right1 = ExpressionLambdaToSql(callExp.Arguments[argIndex], _tables, _selectColumnMap, getSelectGroupingMapString, tbtype, isQuoteName);
if (left.StartsWith("array[") || left.EndsWith("]"))
return $"{right1} 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(')')}]";
return $"({left} @> array[{right1}])";
case "Concat": case "Concat":
if (left.StartsWith("(") || left.EndsWith(")")) left = $"array[{left.TrimStart('(').TrimEnd(')')}]";
var right2 = ExpressionLambdaToSql(callExp.Arguments[argIndex], _tables, _selectColumnMap, getSelectGroupingMapString, tbtype, isQuoteName); var right2 = ExpressionLambdaToSql(callExp.Arguments[argIndex], _tables, _selectColumnMap, getSelectGroupingMapString, tbtype, isQuoteName);
if (right2.StartsWith("(") || right2.EndsWith(")")) right2 = $"array[{right2.TrimStart('(').TrimEnd(')')}]"; if (right2.StartsWith("(") || right2.EndsWith(")")) right2 = $"array[{right2.TrimStart('(').TrimEnd(')')}]";
return $"({left} || {right2})"; return $"({left} || {right2})";
case "GetLength": case "GetLength":
case "GetLongLength": case "GetLongLength":
case "Length": case "Length":
case "Count": return $"case when {left} is null then 0 else array_length({left},1) end"; case "Count":
if (left.StartsWith("(") || left.EndsWith(")")) left = $"array[{left.TrimStart('(').TrimEnd(')')}]";
return $"case when {left} is null then 0 else array_length({left},1) end";
} }
} }
switch (objType.FullName) { switch (objType.FullName) {
@ -92,8 +104,8 @@ namespace FreeSql.PostgreSQL {
var memParentExp = memExp.Expression?.Type; var memParentExp = memExp.Expression?.Type;
if (memParentExp?.FullName == "System.Byte[]") return null; if (memParentExp?.FullName == "System.Byte[]") return null;
if (memParentExp != null) { if (memParentExp != null) {
var left = ExpressionLambdaToSql(memExp.Expression, _tables, _selectColumnMap, getSelectGroupingMapString, tbtype, isQuoteName);
if (memParentExp.IsArray == true) { if (memParentExp.IsArray == true) {
var left = ExpressionLambdaToSql(memExp.Expression, _tables, _selectColumnMap, getSelectGroupingMapString, tbtype, isQuoteName);
if (left.StartsWith("(") || left.EndsWith(")")) left = $"array[{left.TrimStart('(').TrimEnd(')')}]"; if (left.StartsWith("(") || left.EndsWith(")")) left = $"array[{left.TrimStart('(').TrimEnd(')')}]";
switch (memExp.Member.Name) { switch (memExp.Member.Name) {
case "Length": case "Length":
@ -104,12 +116,14 @@ namespace FreeSql.PostgreSQL {
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":
var left = ExpressionLambdaToSql(memExp.Expression, _tables, _selectColumnMap, getSelectGroupingMapString, tbtype, isQuoteName);
switch (memExp.Member.Name) { switch (memExp.Member.Name) {
case "Count": return $"jsonb_array_length(coalesce({left},'[]'))"; case "Count": return $"jsonb_array_length(coalesce({left},'[]'))";
} }
break; break;
} }
if (memParentExp.FullName == typeof(Dictionary<string, string>).FullName) { if (memParentExp.FullName == typeof(Dictionary<string, string>).FullName) {
var left = ExpressionLambdaToSql(memExp.Expression, _tables, _selectColumnMap, getSelectGroupingMapString, tbtype, isQuoteName);
switch (memExp.Member.Name) { switch (memExp.Member.Name) {
case "Count": return $"case when {left} is null then 0 else array_length(akeys({left}),1) end"; case "Count": return $"case when {left} is null then 0 else array_length(akeys({left}),1) end";
case "Keys": return $"akeys({left})"; case "Keys": return $"akeys({left})";
@ -199,66 +213,74 @@ namespace FreeSql.PostgreSQL {
} }
internal override string ExpressionLambdaToSqlCallString(MethodCallExpression exp, List<SelectTableInfo> _tables, List<SelectColumnInfo> _selectColumnMap, Func<Expression[], string> getSelectGroupingMapString, SelectTableInfoType tbtype, bool isQuoteName) { internal override string ExpressionLambdaToSqlCallString(MethodCallExpression exp, List<SelectTableInfo> _tables, List<SelectColumnInfo> _selectColumnMap, Func<Expression[], string> getSelectGroupingMapString, SelectTableInfoType tbtype, bool isQuoteName) {
var left = ExpressionLambdaToSql(exp.Object, _tables, _selectColumnMap, getSelectGroupingMapString, tbtype, isQuoteName); if (exp.Object == null) {
switch (exp.Method.Name) { switch (exp.Method.Name) {
case "StartsWith": case "IsNullOrEmpty":
case "EndsWith": var arg1 = ExpressionLambdaToSql(exp.Arguments[0], _tables, _selectColumnMap, getSelectGroupingMapString, tbtype, isQuoteName);
case "Contains": return $"({arg1} is null or {arg1} = '')";
var args0Value = ExpressionLambdaToSql(exp.Arguments[0], _tables, _selectColumnMap, getSelectGroupingMapString, tbtype, isQuoteName); }
if (args0Value == "NULL") return $"({left}) IS NULL"; } else {
var likeOpt = "LIKE"; var left = ExpressionLambdaToSql(exp.Object, _tables, _selectColumnMap, getSelectGroupingMapString, tbtype, isQuoteName);
if (exp.Arguments.Count > 1) { switch (exp.Method.Name) {
if (exp.Arguments[1].Type == typeof(bool) || case "StartsWith":
exp.Arguments[1].Type == typeof(StringComparison) && ExpressionLambdaToSql(exp.Arguments[0], _tables, _selectColumnMap, getSelectGroupingMapString, tbtype, isQuoteName).Contains("IgnoreCase")) likeOpt = "ILIKE"; case "EndsWith":
} case "Contains":
if (exp.Method.Name == "StartsWith") return $"({left}) {likeOpt} {(args0Value.EndsWith("'") ? args0Value.Insert(args0Value.Length - 1, "%") : $"(({args0Value})::varchar || '%')")}"; var args0Value = ExpressionLambdaToSql(exp.Arguments[0], _tables, _selectColumnMap, getSelectGroupingMapString, tbtype, isQuoteName);
if (exp.Method.Name == "EndsWith") return $"({left}) {likeOpt} {(args0Value.StartsWith("'") ? args0Value.Insert(1, "%") : $"('%' || ({args0Value})::varchar)")}"; if (args0Value == "NULL") return $"({left}) IS NULL";
if (args0Value.StartsWith("'") && args0Value.EndsWith("'")) return $"({left}) {likeOpt} {args0Value.Insert(1, "%").Insert(args0Value.Length, "%")}"; var likeOpt = "LIKE";
return $"({left}) {likeOpt} ('%' || ({args0Value})::varchar || '%')"; if (exp.Arguments.Count > 1) {
case "ToLower": return $"lower({left})"; if (exp.Arguments[1].Type == typeof(bool) ||
case "ToUpper": return $"upper({left})"; exp.Arguments[1].Type == typeof(StringComparison) && ExpressionLambdaToSql(exp.Arguments[0], _tables, _selectColumnMap, getSelectGroupingMapString, tbtype, isQuoteName).Contains("IgnoreCase")) likeOpt = "ILIKE";
case "Substring":
var substrArgs1 = ExpressionLambdaToSql(exp.Arguments[0], _tables, _selectColumnMap, getSelectGroupingMapString, tbtype, isQuoteName);
if (long.TryParse(substrArgs1, out var testtrylng1)) substrArgs1 = (testtrylng1 + 1).ToString();
else substrArgs1 += "+1";
if (exp.Arguments.Count == 1) return $"substr({left}, {substrArgs1})";
return $"substr({left}, {substrArgs1}, {ExpressionLambdaToSql(exp.Arguments[1], _tables, _selectColumnMap, getSelectGroupingMapString, tbtype, isQuoteName)})";
case "IndexOf": return $"(strpos({left}, {ExpressionLambdaToSql(exp.Arguments[0], _tables, _selectColumnMap, getSelectGroupingMapString, tbtype, isQuoteName)})-1)";
case "PadLeft":
if (exp.Arguments.Count == 1) return $"lpad({left}, {ExpressionLambdaToSql(exp.Arguments[0], _tables, _selectColumnMap, getSelectGroupingMapString, tbtype, isQuoteName)})";
return $"lpad({left}, {ExpressionLambdaToSql(exp.Arguments[0], _tables, _selectColumnMap, getSelectGroupingMapString, tbtype, isQuoteName)}, {ExpressionLambdaToSql(exp.Arguments[1], _tables, _selectColumnMap, getSelectGroupingMapString, tbtype, isQuoteName)})";
case "PadRight":
if (exp.Arguments.Count == 1) return $"rpad({left}, {ExpressionLambdaToSql(exp.Arguments[0], _tables, _selectColumnMap, getSelectGroupingMapString, tbtype, isQuoteName)})";
return $"rpad({left}, {ExpressionLambdaToSql(exp.Arguments[0], _tables, _selectColumnMap, getSelectGroupingMapString, tbtype, isQuoteName)}, {ExpressionLambdaToSql(exp.Arguments[1], _tables, _selectColumnMap, getSelectGroupingMapString, tbtype, isQuoteName)})";
case "Trim":
case "TrimStart":
case "TrimEnd":
if (exp.Arguments.Count == 0) {
if (exp.Method.Name == "Trim") return $"trim({left})";
if (exp.Method.Name == "TrimStart") return $"ltrim({left})";
if (exp.Method.Name == "TrimEnd") return $"rtrim({left})";
}
var trimArg1 = "";
var trimArg2 = "";
foreach (var argsTrim02 in exp.Arguments) {
var argsTrim01s = new[] { argsTrim02 };
if (argsTrim02.NodeType == ExpressionType.NewArrayInit) {
var arritem = argsTrim02 as NewArrayExpression;
argsTrim01s = arritem.Expressions.ToArray();
} }
foreach (var argsTrim01 in argsTrim01s) { if (exp.Method.Name == "StartsWith") return $"({left}) {likeOpt} {(args0Value.EndsWith("'") ? args0Value.Insert(args0Value.Length - 1, "%") : $"(({args0Value})::varchar || '%')")}";
var trimChr = ExpressionLambdaToSql(argsTrim01, _tables, _selectColumnMap, getSelectGroupingMapString, tbtype, isQuoteName).Trim('\''); if (exp.Method.Name == "EndsWith") return $"({left}) {likeOpt} {(args0Value.StartsWith("'") ? args0Value.Insert(1, "%") : $"('%' || ({args0Value})::varchar)")}";
if (trimChr.Length == 1) trimArg1 += trimChr; if (args0Value.StartsWith("'") && args0Value.EndsWith("'")) return $"({left}) {likeOpt} {args0Value.Insert(1, "%").Insert(args0Value.Length, "%")}";
else trimArg2 += $" || ({trimChr})"; return $"({left}) {likeOpt} ('%' || ({args0Value})::varchar || '%')";
case "ToLower": return $"lower({left})";
case "ToUpper": return $"upper({left})";
case "Substring":
var substrArgs1 = ExpressionLambdaToSql(exp.Arguments[0], _tables, _selectColumnMap, getSelectGroupingMapString, tbtype, isQuoteName);
if (long.TryParse(substrArgs1, out var testtrylng1)) substrArgs1 = (testtrylng1 + 1).ToString();
else substrArgs1 += "+1";
if (exp.Arguments.Count == 1) return $"substr({left}, {substrArgs1})";
return $"substr({left}, {substrArgs1}, {ExpressionLambdaToSql(exp.Arguments[1], _tables, _selectColumnMap, getSelectGroupingMapString, tbtype, isQuoteName)})";
case "IndexOf": return $"(strpos({left}, {ExpressionLambdaToSql(exp.Arguments[0], _tables, _selectColumnMap, getSelectGroupingMapString, tbtype, isQuoteName)})-1)";
case "PadLeft":
if (exp.Arguments.Count == 1) return $"lpad({left}, {ExpressionLambdaToSql(exp.Arguments[0], _tables, _selectColumnMap, getSelectGroupingMapString, tbtype, isQuoteName)})";
return $"lpad({left}, {ExpressionLambdaToSql(exp.Arguments[0], _tables, _selectColumnMap, getSelectGroupingMapString, tbtype, isQuoteName)}, {ExpressionLambdaToSql(exp.Arguments[1], _tables, _selectColumnMap, getSelectGroupingMapString, tbtype, isQuoteName)})";
case "PadRight":
if (exp.Arguments.Count == 1) return $"rpad({left}, {ExpressionLambdaToSql(exp.Arguments[0], _tables, _selectColumnMap, getSelectGroupingMapString, tbtype, isQuoteName)})";
return $"rpad({left}, {ExpressionLambdaToSql(exp.Arguments[0], _tables, _selectColumnMap, getSelectGroupingMapString, tbtype, isQuoteName)}, {ExpressionLambdaToSql(exp.Arguments[1], _tables, _selectColumnMap, getSelectGroupingMapString, tbtype, isQuoteName)})";
case "Trim":
case "TrimStart":
case "TrimEnd":
if (exp.Arguments.Count == 0) {
if (exp.Method.Name == "Trim") return $"trim({left})";
if (exp.Method.Name == "TrimStart") return $"ltrim({left})";
if (exp.Method.Name == "TrimEnd") return $"rtrim({left})";
} }
} var trimArg1 = "";
if (exp.Method.Name == "Trim") left = $"trim({left}, {_common.FormatSql("{0}", trimArg1)}{trimArg2})"; var trimArg2 = "";
if (exp.Method.Name == "TrimStart") left = $"ltrim({left}, {_common.FormatSql("{0}", trimArg1)}{trimArg2})"; foreach (var argsTrim02 in exp.Arguments) {
if (exp.Method.Name == "TrimEnd") left = $"rtrim({left}, {_common.FormatSql("{0}", trimArg1)}{trimArg2})"; var argsTrim01s = new[] { argsTrim02 };
return left; if (argsTrim02.NodeType == ExpressionType.NewArrayInit) {
case "Replace": return $"replace({left}, {ExpressionLambdaToSql(exp.Arguments[0], _tables, _selectColumnMap, getSelectGroupingMapString, tbtype, isQuoteName)}, {ExpressionLambdaToSql(exp.Arguments[1], _tables, _selectColumnMap, getSelectGroupingMapString, tbtype, isQuoteName)})"; var arritem = argsTrim02 as NewArrayExpression;
case "CompareTo": return $"case when {left} = {ExpressionLambdaToSql(exp.Arguments[0], _tables, _selectColumnMap, getSelectGroupingMapString, tbtype, isQuoteName)} then 0 when {left} > {ExpressionLambdaToSql(exp.Arguments[0], _tables, _selectColumnMap, getSelectGroupingMapString, tbtype, isQuoteName)} then 1 else -1 end"; argsTrim01s = arritem.Expressions.ToArray();
case "Equals": return $"({left} = ({ExpressionLambdaToSql(exp.Arguments[0], _tables, _selectColumnMap, getSelectGroupingMapString, tbtype, isQuoteName)})::varchar)"; }
foreach (var argsTrim01 in argsTrim01s) {
var trimChr = ExpressionLambdaToSql(argsTrim01, _tables, _selectColumnMap, getSelectGroupingMapString, tbtype, isQuoteName).Trim('\'');
if (trimChr.Length == 1) trimArg1 += trimChr;
else trimArg2 += $" || ({trimChr})";
}
}
if (exp.Method.Name == "Trim") left = $"trim({left}, {_common.FormatSql("{0}", trimArg1)}{trimArg2})";
if (exp.Method.Name == "TrimStart") left = $"ltrim({left}, {_common.FormatSql("{0}", trimArg1)}{trimArg2})";
if (exp.Method.Name == "TrimEnd") left = $"rtrim({left}, {_common.FormatSql("{0}", trimArg1)}{trimArg2})";
return left;
case "Replace": return $"replace({left}, {ExpressionLambdaToSql(exp.Arguments[0], _tables, _selectColumnMap, getSelectGroupingMapString, tbtype, isQuoteName)}, {ExpressionLambdaToSql(exp.Arguments[1], _tables, _selectColumnMap, getSelectGroupingMapString, tbtype, isQuoteName)})";
case "CompareTo": return $"case when {left} = {ExpressionLambdaToSql(exp.Arguments[0], _tables, _selectColumnMap, getSelectGroupingMapString, tbtype, isQuoteName)} then 0 when {left} > {ExpressionLambdaToSql(exp.Arguments[0], _tables, _selectColumnMap, getSelectGroupingMapString, tbtype, isQuoteName)} then 1 else -1 end";
case "Equals": return $"({left} = ({ExpressionLambdaToSql(exp.Arguments[0], _tables, _selectColumnMap, getSelectGroupingMapString, tbtype, isQuoteName)})::varchar)";
}
} }
throw new Exception($"PostgreSQLExpression 未现实函数表达式 {exp} 解析"); throw new Exception($"PostgreSQLExpression 未现实函数表达式 {exp} 解析");
} }

View File

@ -4,6 +4,7 @@ using System;
using System.Collections.Generic; using System.Collections.Generic;
using System.Linq; using System.Linq;
using System.Linq.Expressions; using System.Linq.Expressions;
using System.Text;
namespace FreeSql.SqlServer { namespace FreeSql.SqlServer {
class SqlServerExpression : CommonExpression { class SqlServerExpression : CommonExpression {
@ -11,6 +12,41 @@ namespace FreeSql.SqlServer {
public SqlServerExpression(CommonUtils common) : base(common) { } public SqlServerExpression(CommonUtils common) : base(common) { }
internal override string ExpressionLambdaToSqlOther(Expression exp, List<SelectTableInfo> _tables, List<SelectColumnInfo> _selectColumnMap, Func<Expression[], string> getSelectGroupingMapString, SelectTableInfoType tbtype, bool isQuoteName) { internal override string ExpressionLambdaToSqlOther(Expression exp, List<SelectTableInfo> _tables, List<SelectColumnInfo> _selectColumnMap, Func<Expression[], string> getSelectGroupingMapString, SelectTableInfoType tbtype, bool isQuoteName) {
switch (exp.NodeType) {
case ExpressionType.Call:
var callExp = exp as MethodCallExpression;
var objExp = callExp.Object;
var objType = objExp?.Type;
if (objType?.FullName == "System.Byte[]") return null;
var argIndex = 0;
if (objType == null && callExp.Method.DeclaringType.FullName == typeof(Enumerable).FullName) {
objExp = callExp.Arguments.FirstOrDefault();
objType = objExp?.Type;
argIndex++;
}
if (objType == null) objType = callExp.Method.DeclaringType;
if (objType != null) {
var left = objExp == null ? null : ExpressionLambdaToSql(objExp, _tables, _selectColumnMap, getSelectGroupingMapString, tbtype, isQuoteName);
if (objType.IsArray == true) {
switch (callExp.Method.Name) {
case "Contains":
//判断 in
return $"({ExpressionLambdaToSql(callExp.Arguments[argIndex], _tables, _selectColumnMap, getSelectGroupingMapString, tbtype, isQuoteName)}) in {left}";
}
}
}
break;
case ExpressionType.NewArrayInit:
var arrExp = exp as NewArrayExpression;
var arrSb = new StringBuilder();
arrSb.Append("(");
for (var a = 0; a < arrExp.Expressions.Count; a++) {
if (a > 0) arrSb.Append(",");
arrSb.Append(ExpressionLambdaToSql(arrExp.Expressions[a], _tables, _selectColumnMap, getSelectGroupingMapString, tbtype, isQuoteName));
}
return arrSb.Append(")").ToString();
}
return null; return null;
} }
@ -82,46 +118,54 @@ namespace FreeSql.SqlServer {
} }
internal override string ExpressionLambdaToSqlCallString(MethodCallExpression exp, List<SelectTableInfo> _tables, List<SelectColumnInfo> _selectColumnMap, Func<Expression[], string> getSelectGroupingMapString, SelectTableInfoType tbtype, bool isQuoteName) { internal override string ExpressionLambdaToSqlCallString(MethodCallExpression exp, List<SelectTableInfo> _tables, List<SelectColumnInfo> _selectColumnMap, Func<Expression[], string> getSelectGroupingMapString, SelectTableInfoType tbtype, bool isQuoteName) {
var left = ExpressionLambdaToSql(exp.Object, _tables, _selectColumnMap, getSelectGroupingMapString, tbtype, isQuoteName); if (exp.Object == null) {
switch (exp.Method.Name) { switch (exp.Method.Name) {
case "StartsWith": case "IsNullOrEmpty":
case "EndsWith": var arg1 = ExpressionLambdaToSql(exp.Arguments[0], _tables, _selectColumnMap, getSelectGroupingMapString, tbtype, isQuoteName);
case "Contains": return $"({arg1} is null or {arg1} = '')";
var args0Value = ExpressionLambdaToSql(exp.Arguments[0], _tables, _selectColumnMap, getSelectGroupingMapString, tbtype, isQuoteName); }
if (args0Value == "NULL") return $"({left}) IS NULL"; } else {
if (exp.Method.Name == "StartsWith") return $"({left}) LIKE {(args0Value.EndsWith("'") ? args0Value.Insert(args0Value.Length - 1, "%") : $"(cast({args0Value} as nvarchar)+'%')")}"; var left = ExpressionLambdaToSql(exp.Object, _tables, _selectColumnMap, getSelectGroupingMapString, tbtype, isQuoteName);
if (exp.Method.Name == "EndsWith") return $"({left}) LIKE {(args0Value.StartsWith("'") ? args0Value.Insert(1, "%") : $"('%'+cast({args0Value} as nvarchar))")}"; switch (exp.Method.Name) {
if (args0Value.StartsWith("'") && args0Value.EndsWith("'")) return $"({left}) LIKE {args0Value.Insert(1, "%").Insert(args0Value.Length, "%")}"; case "StartsWith":
return $"({left}) LIKE ('%'+cast({args0Value} as nvarchar)+'%')"; case "EndsWith":
case "ToLower": return $"lower({left})"; case "Contains":
case "ToUpper": return $"upper({left})"; var args0Value = ExpressionLambdaToSql(exp.Arguments[0], _tables, _selectColumnMap, getSelectGroupingMapString, tbtype, isQuoteName);
case "Substring": if (args0Value == "NULL") return $"({left}) IS NULL";
var substrArgs1 = ExpressionLambdaToSql(exp.Arguments[0], _tables, _selectColumnMap, getSelectGroupingMapString, tbtype, isQuoteName); if (exp.Method.Name == "StartsWith") return $"({left}) LIKE {(args0Value.EndsWith("'") ? args0Value.Insert(args0Value.Length - 1, "%") : $"(cast({args0Value} as nvarchar)+'%')")}";
if (long.TryParse(substrArgs1, out var testtrylng1)) substrArgs1 = (testtrylng1 + 1).ToString(); if (exp.Method.Name == "EndsWith") return $"({left}) LIKE {(args0Value.StartsWith("'") ? args0Value.Insert(1, "%") : $"('%'+cast({args0Value} as nvarchar))")}";
else substrArgs1 += "+1"; if (args0Value.StartsWith("'") && args0Value.EndsWith("'")) return $"({left}) LIKE {args0Value.Insert(1, "%").Insert(args0Value.Length, "%")}";
if (exp.Arguments.Count == 1) return $"left({left}, {substrArgs1})"; return $"({left}) LIKE ('%'+cast({args0Value} as nvarchar)+'%')";
return $"substring({left}, {substrArgs1}, {ExpressionLambdaToSql(exp.Arguments[1], _tables, _selectColumnMap, getSelectGroupingMapString, tbtype, isQuoteName)})"; case "ToLower": return $"lower({left})";
case "IndexOf": case "ToUpper": return $"upper({left})";
var indexOfFindStr = ExpressionLambdaToSql(exp.Arguments[0], _tables, _selectColumnMap, getSelectGroupingMapString, tbtype, isQuoteName); case "Substring":
if (exp.Arguments.Count > 1 && exp.Arguments[1].Type.FullName == "System.Int32") { var substrArgs1 = ExpressionLambdaToSql(exp.Arguments[0], _tables, _selectColumnMap, getSelectGroupingMapString, tbtype, isQuoteName);
var locateArgs1 = ExpressionLambdaToSql(exp.Arguments[1], _tables, _selectColumnMap, getSelectGroupingMapString, tbtype, isQuoteName); if (long.TryParse(substrArgs1, out var testtrylng1)) substrArgs1 = (testtrylng1 + 1).ToString();
if (long.TryParse(locateArgs1, out var testtrylng2)) locateArgs1 = (testtrylng2 + 1).ToString(); else substrArgs1 += "+1";
else locateArgs1 += "+1"; if (exp.Arguments.Count == 1) return $"left({left}, {substrArgs1})";
return $"(charindex({left}, {indexOfFindStr}, {locateArgs1})-1)"; return $"substring({left}, {substrArgs1}, {ExpressionLambdaToSql(exp.Arguments[1], _tables, _selectColumnMap, getSelectGroupingMapString, tbtype, isQuoteName)})";
} case "IndexOf":
return $"(charindex({left}, {indexOfFindStr})-1)"; var indexOfFindStr = ExpressionLambdaToSql(exp.Arguments[0], _tables, _selectColumnMap, getSelectGroupingMapString, tbtype, isQuoteName);
case "PadLeft": if (exp.Arguments.Count > 1 && exp.Arguments[1].Type.FullName == "System.Int32") {
if (exp.Arguments.Count == 1) return $"lpad({left}, {ExpressionLambdaToSql(exp.Arguments[0], _tables, _selectColumnMap, getSelectGroupingMapString, tbtype, isQuoteName)})"; var locateArgs1 = ExpressionLambdaToSql(exp.Arguments[1], _tables, _selectColumnMap, getSelectGroupingMapString, tbtype, isQuoteName);
return $"lpad({left}, {ExpressionLambdaToSql(exp.Arguments[0], _tables, _selectColumnMap, getSelectGroupingMapString, tbtype, isQuoteName)}, {ExpressionLambdaToSql(exp.Arguments[1], _tables, _selectColumnMap, getSelectGroupingMapString, tbtype, isQuoteName)})"; if (long.TryParse(locateArgs1, out var testtrylng2)) locateArgs1 = (testtrylng2 + 1).ToString();
case "PadRight": else locateArgs1 += "+1";
if (exp.Arguments.Count == 1) return $"rpad({left}, {ExpressionLambdaToSql(exp.Arguments[0], _tables, _selectColumnMap, getSelectGroupingMapString, tbtype, isQuoteName)})"; return $"(charindex({left}, {indexOfFindStr}, {locateArgs1})-1)";
return $"rpad({left}, {ExpressionLambdaToSql(exp.Arguments[0], _tables, _selectColumnMap, getSelectGroupingMapString, tbtype, isQuoteName)}, {ExpressionLambdaToSql(exp.Arguments[1], _tables, _selectColumnMap, getSelectGroupingMapString, tbtype, isQuoteName)})"; }
case "Trim": return $"ltrim(rtrim({left}))"; return $"(charindex({left}, {indexOfFindStr})-1)";
case "TrimStart": return $"ltrim({left})"; case "PadLeft":
case "TrimEnd": return $"rtrim({left})"; if (exp.Arguments.Count == 1) return $"lpad({left}, {ExpressionLambdaToSql(exp.Arguments[0], _tables, _selectColumnMap, getSelectGroupingMapString, tbtype, isQuoteName)})";
case "Replace": return $"replace({left}, {ExpressionLambdaToSql(exp.Arguments[0], _tables, _selectColumnMap, getSelectGroupingMapString, tbtype, isQuoteName)}, {ExpressionLambdaToSql(exp.Arguments[1], _tables, _selectColumnMap, getSelectGroupingMapString, tbtype, isQuoteName)})"; return $"lpad({left}, {ExpressionLambdaToSql(exp.Arguments[0], _tables, _selectColumnMap, getSelectGroupingMapString, tbtype, isQuoteName)}, {ExpressionLambdaToSql(exp.Arguments[1], _tables, _selectColumnMap, getSelectGroupingMapString, tbtype, isQuoteName)})";
case "CompareTo": return $"({left} - {ExpressionLambdaToSql(exp.Arguments[0], _tables, _selectColumnMap, getSelectGroupingMapString, tbtype, isQuoteName)})"; case "PadRight":
case "Equals": return $"({left} = {ExpressionLambdaToSql(exp.Arguments[0], _tables, _selectColumnMap, getSelectGroupingMapString, tbtype, isQuoteName)})"; if (exp.Arguments.Count == 1) return $"rpad({left}, {ExpressionLambdaToSql(exp.Arguments[0], _tables, _selectColumnMap, getSelectGroupingMapString, tbtype, isQuoteName)})";
return $"rpad({left}, {ExpressionLambdaToSql(exp.Arguments[0], _tables, _selectColumnMap, getSelectGroupingMapString, tbtype, isQuoteName)}, {ExpressionLambdaToSql(exp.Arguments[1], _tables, _selectColumnMap, getSelectGroupingMapString, tbtype, isQuoteName)})";
case "Trim": return $"ltrim(rtrim({left}))";
case "TrimStart": return $"ltrim({left})";
case "TrimEnd": return $"rtrim({left})";
case "Replace": return $"replace({left}, {ExpressionLambdaToSql(exp.Arguments[0], _tables, _selectColumnMap, getSelectGroupingMapString, tbtype, isQuoteName)}, {ExpressionLambdaToSql(exp.Arguments[1], _tables, _selectColumnMap, getSelectGroupingMapString, tbtype, isQuoteName)})";
case "CompareTo": return $"({left} - {ExpressionLambdaToSql(exp.Arguments[0], _tables, _selectColumnMap, getSelectGroupingMapString, tbtype, isQuoteName)})";
case "Equals": return $"({left} = {ExpressionLambdaToSql(exp.Arguments[0], _tables, _selectColumnMap, getSelectGroupingMapString, tbtype, isQuoteName)})";
}
} }
throw new Exception($"SqlServerExpression 未现实函数表达式 {exp} 解析"); throw new Exception($"SqlServerExpression 未现实函数表达式 {exp} 解析");
} }