mysql 表达式函数测试完成

This commit is contained in:
28810
2018-12-21 17:03:51 +08:00
parent 572aa1d8ee
commit 2a07c8bae6
14 changed files with 1454 additions and 410 deletions

View File

@ -155,26 +155,31 @@ namespace FreeSql.Internal {
}
internal string ExpressionLambdaToSql(Expression exp, List<SelectTableInfo> _tables, List<SelectColumnInfo> _selectColumnMap, SelectTableInfoType tbtype, bool isQuoteName) {
switch( exp.NodeType) {
switch (exp.NodeType) {
case ExpressionType.Quote: return ExpressionLambdaToSql((exp as UnaryExpression)?.Operand, _tables, _selectColumnMap, tbtype, isQuoteName);
case ExpressionType.Lambda: return ExpressionLambdaToSql((exp as LambdaExpression)?.Body, _tables, _selectColumnMap, tbtype, isQuoteName);
case ExpressionType.Convert: return ExpressionLambdaToSql((exp as UnaryExpression)?.Operand, _tables, _selectColumnMap, tbtype, isQuoteName);
case ExpressionType.Negate:
case ExpressionType.NegateChecked: return "-" + ExpressionLambdaToSql((exp as UnaryExpression)?.Operand, _tables, _selectColumnMap, tbtype, isQuoteName);
case ExpressionType.Constant: return _common.FormatSql("{0}", (exp as ConstantExpression)?.Value);
case ExpressionType.Call:
var exp3 = exp as MethodCallExpression;
if (exp3.Object.Type.FullName == "System.String") return ExpressionLambdaToSqlCallString(exp3, _tables, _selectColumnMap, tbtype, isQuoteName);
if (exp3.Object.Type.FullName == "System.Math") return ExpressionLambdaToSqlCallMath(exp3, _tables, _selectColumnMap, tbtype, isQuoteName);
if (exp3.Object.Type.FullName == "System.DateTime" || exp3.Object.Type.GenericTypeArguments.FirstOrDefault()?.FullName == "System.DateTime") return ExpressionLambdaToSqlCallDateTime(exp3, _tables, _selectColumnMap, tbtype, isQuoteName);
if (exp3.Object.Type.FullName == "System.TimeSpan" || exp3.Object.Type.GenericTypeArguments.FirstOrDefault()?.FullName == "System.TimeSpan") return ExpressionLambdaToSqlCallTimeSpan(exp3, _tables, _selectColumnMap, tbtype, isQuoteName);
switch (exp3.Object?.Type.FullName ?? exp3.Method.DeclaringType.FullName) {
case "System.String": return ExpressionLambdaToSqlCallString(exp3, _tables, _selectColumnMap, tbtype, isQuoteName);
case "System.Math": return ExpressionLambdaToSqlCallMath(exp3, _tables, _selectColumnMap, tbtype, isQuoteName);
case "System.DateTime": return ExpressionLambdaToSqlCallDateTime(exp3, _tables, _selectColumnMap, tbtype, isQuoteName);
case "System.TimeSpan": return ExpressionLambdaToSqlCallTimeSpan(exp3, _tables, _selectColumnMap, tbtype, isQuoteName);
}
throw new Exception($"MySqlExpression 未现实函数表达式 {exp3} 解析");
case ExpressionType.MemberAccess:
var exp4 = exp as MemberExpression;
if (exp4.Expression != null && exp4.Expression.Type.FullName.StartsWith("System.Nullable`1[")) return ExpressionLambdaToSql(exp4.Expression, _tables, _selectColumnMap, tbtype, isQuoteName);
var extRet = "";
if (exp4.Expression == null && exp4.Type.FullName == "System.DateTime" && exp4.Member.Name == "Now") return ExpressionLambdaToSqlMemberAccessDateTime(exp4, _tables, _selectColumnMap, tbtype, isQuoteName);
if (exp4.Expression.Type.FullName == "System.String") extRet = ExpressionLambdaToSqlMemberAccessString(exp4, _tables, _selectColumnMap, tbtype, isQuoteName);
else if (exp4.Expression.Type.FullName == "System.Math") extRet = ExpressionLambdaToSqlMemberAccessMath(exp4, _tables, _selectColumnMap, tbtype, isQuoteName);
else if (exp4.Expression.Type.FullName == "System.DateTime" || exp4.Type.GenericTypeArguments.FirstOrDefault()?.FullName == "System.DateTime") extRet = ExpressionLambdaToSqlMemberAccessDateTime(exp4, _tables, _selectColumnMap, tbtype, isQuoteName);
else if (exp4.Expression.Type.FullName == "System.TimeSpan" || exp4.Type.GenericTypeArguments.FirstOrDefault()?.FullName == "System.TimeSpan") extRet = ExpressionLambdaToSqlMemberAccessTimeSpan(exp4, _tables, _selectColumnMap, tbtype, isQuoteName);
switch (exp4.Expression?.Type.FullName ?? exp4.Type.FullName) {
case "System.String": extRet = ExpressionLambdaToSqlMemberAccessString(exp4, _tables, _selectColumnMap, tbtype, isQuoteName); break;
case "System.DateTime": extRet = ExpressionLambdaToSqlMemberAccessDateTime(exp4, _tables, _selectColumnMap, tbtype, isQuoteName); break;
case "System.TimeSpan": extRet = ExpressionLambdaToSqlMemberAccessTimeSpan(exp4, _tables, _selectColumnMap, tbtype, isQuoteName); break;
}
if (string.IsNullOrEmpty(extRet) == false) return extRet;
var expStack = new Stack<Expression>();
@ -272,9 +277,14 @@ namespace FreeSql.Internal {
if (isQuoteName) name2 = _common.QuoteSqlName(name2);
return $"{alias2}.{name2}";
}
if (dicExpressionOperator.TryGetValue(exp.NodeType, out var tryoper) == false) return "";
var expBinary = exp as BinaryExpression;
if (expBinary == null) return "";
if (expBinary.NodeType == ExpressionType.Coalesce) {
return _common.IsNull(
ExpressionLambdaToSql(expBinary.Left, _tables, _selectColumnMap, tbtype, isQuoteName),
ExpressionLambdaToSql(expBinary.Right, _tables, _selectColumnMap, tbtype, isQuoteName));
}
if (dicExpressionOperator.TryGetValue(expBinary.NodeType, out var tryoper) == false) return "";
var left = ExpressionLambdaToSql(expBinary.Left, _tables, _selectColumnMap, tbtype, isQuoteName);
var right = ExpressionLambdaToSql(expBinary.Right, _tables, _selectColumnMap, tbtype, isQuoteName);
if (left == "NULL") {
@ -288,7 +298,6 @@ namespace FreeSql.Internal {
}
internal abstract string ExpressionLambdaToSqlMemberAccessString(MemberExpression exp, List<SelectTableInfo> _tables, List<SelectColumnInfo> _selectColumnMap, SelectTableInfoType tbtype, bool isQuoteName);
internal abstract string ExpressionLambdaToSqlMemberAccessMath(MemberExpression exp, List<SelectTableInfo> _tables, List<SelectColumnInfo> _selectColumnMap, SelectTableInfoType tbtype, bool isQuoteName);
internal abstract string ExpressionLambdaToSqlMemberAccessDateTime(MemberExpression exp, List<SelectTableInfo> _tables, List<SelectColumnInfo> _selectColumnMap, SelectTableInfoType tbtype, bool isQuoteName);
internal abstract string ExpressionLambdaToSqlMemberAccessTimeSpan(MemberExpression exp, List<SelectTableInfo> _tables, List<SelectColumnInfo> _selectColumnMap, SelectTableInfoType tbtype, bool isQuoteName);
internal abstract string ExpressionLambdaToSqlCallString(MethodCallExpression exp, List<SelectTableInfo> _tables, List<SelectColumnInfo> _selectColumnMap, SelectTableInfoType tbtype, bool isQuoteName);

View File

@ -38,13 +38,11 @@ namespace FreeSql.MySql {
return string.Concat("'", ((DateTime)param).ToString("yyyy-MM-dd HH:mm:ss"), "'");
else if (param is DateTime?)
return string.Concat("'", (param as DateTime?).Value.ToString("yyyy-MM-dd HH:mm:ss"), "'");
else if (param is TimeSpan) {
var ts = (TimeSpan)param;
return string.Concat("'", ts.Ticks > 0 ? "" : "-", ts.TotalHours, dt1970.AddTicks(Math.Abs(ts.Ticks)).ToString(":mm:ss.fff"), "'");
} else if (param is TimeSpan) {
var ts = (param as TimeSpan?).Value;
return string.Concat("'", ts.Ticks > 0 ? "" : "-", ts.TotalHours, dt1970.AddTicks(Math.Abs(ts.Ticks)).ToString(":mm:ss.fff"), "'");
} else if (param is IEnumerable) {
else if (param is TimeSpan)
return ((TimeSpan)param).Ticks / 10;
else if (param is TimeSpan?)
return (param as TimeSpan?).Value.Ticks / 10;
else if (param is IEnumerable) {
var sb = new StringBuilder();
var ie = param as IEnumerable;
foreach (var z in ie) sb.Append(",").Append(AddslashesProcessParam(z));

View File

@ -11,25 +11,33 @@ namespace FreeSql.MySql {
public MySqlExpression(CommonUtils common) : base(common) { }
internal override string ExpressionLambdaToSqlMemberAccessString(MemberExpression exp, List<SelectTableInfo> _tables, List<SelectColumnInfo> _selectColumnMap, SelectTableInfoType tbtype, bool isQuoteName) {
if (exp.Expression == null) {
switch (exp.Member.Name) {
case "Empty": return "''";
}
return null;
}
var left = ExpressionLambdaToSql(exp.Expression, _tables, _selectColumnMap, tbtype, isQuoteName);
switch (exp.Member.Name) {
case "Length": return $"char_length({left})";
}
return null;
}
internal override string ExpressionLambdaToSqlMemberAccessMath(MemberExpression exp, List<SelectTableInfo> _tables, List<SelectColumnInfo> _selectColumnMap, SelectTableInfoType tbtype, bool isQuoteName) {
var left = ExpressionLambdaToSql(exp.Expression, _tables, _selectColumnMap, tbtype, isQuoteName);
switch (exp.Member.Name) {
case "PI": return $"pi()";
}
return null;
}
internal override string ExpressionLambdaToSqlMemberAccessDateTime(MemberExpression exp, List<SelectTableInfo> _tables, List<SelectColumnInfo> _selectColumnMap, SelectTableInfoType tbtype, bool isQuoteName) {
if (exp.Expression == null && exp.Member.Name == "Now") return "now()";
if (exp.Expression == null) {
switch (exp.Member.Name) {
case "Now": return "now()";
case "UtcNow": return "utc_timestamp()";
case "Today": return "curdate()";
case "MinValue": return "cast('0001/1/1 0:00:00' as datetime)";
case "MaxValue": return "cast('9999/12/31 23:59:59' as datetime)";
}
return null;
}
var left = ExpressionLambdaToSql(exp.Expression, _tables, _selectColumnMap, tbtype, isQuoteName);
switch (exp.Member.Name) {
case "Date": return $"cast(date_format({left}, '%Y-%m-%d') as datetime)";
case "TimeOfDay": return $"(time_to_sec(date_format({left}, '1970-1-1 %H:%i:%s.%f')) * 1000000 + microsecond({left}) + 6213559680000000)";
case "DayOfWeek": return $"(dayofweek({left}) - 1)";
case "Day": return $"dayofmonth({left})";
case "DayOfYear": return $"dayofyear({left})";
@ -39,28 +47,36 @@ namespace FreeSql.MySql {
case "Minute": return $"minute({left})";
case "Second": return $"second({left})";
case "Millisecond": return $"floor(microsecond({left}) / 1000)";
case "Ticks": return $"(time_to_sec({left}) * 10000000 + 621355968000000000)";
case "Ticks": return $"(time_to_sec({left}) * 10000000 + microsecond({left}) * 10 + 62135596800000000)";
}
return null;
}
internal override string ExpressionLambdaToSqlMemberAccessTimeSpan(MemberExpression exp, List<SelectTableInfo> _tables, List<SelectColumnInfo> _selectColumnMap, SelectTableInfoType tbtype, bool isQuoteName) {
if (exp.Expression == null) {
switch (exp.Member.Name) {
case "Zero": return "0";
case "MinValue": return "-922337203685477580"; //微秒 Ticks / 10
case "MaxValue": return "922337203685477580";
}
return null;
}
var left = ExpressionLambdaToSql(exp.Expression, _tables, _selectColumnMap, tbtype, isQuoteName);
switch (exp.Member.Name) {
case "Days": return $"(({left}) div {(long)1000000 * 60 * 60 * 24})";
case "Hours": return $"(({left}) div {(long)1000000 * 60 * 60} mod 24)";
case "Milliseconds": return $"(({left}) div 1000 mod 1000)";
case "Minutes": return $"(({left}) div {(long)1000000 * 60} mod 60)";
case "Seconds": return $"(({left}) div 1000000 mod 60)";
case "Ticks": return $"(({left}) * 10)";
case "TotalDays": return $"(({left}) / {(long)1000000 * 60 * 60 * 24})";
case "TotalHours": return $"(({left}) / {(long)1000000 * 60 * 60})";
case "TotalMilliseconds": return $"(({left}) / 1000)";
case "TotalMinutes": return $"(({left}) / {(long)1000000 * 60})";
case "TotalSeconds": return $"(({left}) / 1000000)";
}
return null;
}
internal override string ExpressionLambdaToSqlMemberAccessTimeSpan(MemberExpression exp, List<SelectTableInfo> _tables, List<SelectColumnInfo> _selectColumnMap, SelectTableInfoType tbtype, bool isQuoteName) {
var left = ExpressionLambdaToSql(exp.Expression, _tables, _selectColumnMap, tbtype, isQuoteName);
switch (exp.Member.Name) {
case "Days": return $"floor(time_to_sec({left}) / {60 * 60 * 24})";
case "Hours": return $"extract(hour from {left})";
case "Milliseconds": return $"floor(extract(microsecond from {left}) / 1000)";
case "Minutes": return $"extract(minute from {left})";
case "Seconds": return $"extract(second from {left})";
case "Ticks": return $"(time_to_sec({left}) * 10000000 + extract(microsecond from {left}) * 10)";
case "TotalDays": return $"floor(extract(hour from {left}) / 24)";
case "TotalHours": return $"floor(time_to_sec({left}) / {60 * 60})";
case "TotalMilliseconds": return $"(time_to_sec({left}) * 1000 + floor(extract(microsecond from {left}) / 1000))";
case "TotalMinutes": return $"floor(time_to_sec({left}) / 60)";
case "TotalSeconds": return $"time_to_sec({left})";
}
return null;
}
internal override string ExpressionLambdaToSqlCallString(MethodCallExpression exp, List<SelectTableInfo> _tables, List<SelectColumnInfo> _selectColumnMap, SelectTableInfoType tbtype, bool isQuoteName) {
var left = ExpressionLambdaToSql(exp.Object, _tables, _selectColumnMap, tbtype, isQuoteName);
switch (exp.Method.Name) {
@ -69,8 +85,8 @@ namespace FreeSql.MySql {
case "Contains":
var args0Value = ExpressionLambdaToSql(exp.Arguments[0], _tables, _selectColumnMap, tbtype, isQuoteName);
if (args0Value == "NULL") return $"({left}) IS NULL";
if (exp.Method.Name == "StartsWith") return $"({left}) LIKE {(args0Value.StartsWith("'") ? args0Value.Insert(1, "%") : $"concat('%', {args0Value})")}";
if (exp.Method.Name == "EndsWith") return $"({left}) LIKE {(args0Value.EndsWith("'") ? args0Value.Insert(args0Value.Length - 1, "%") : $"concat({args0Value}, '%')")}";
if (exp.Method.Name == "StartsWith") return $"({left}) LIKE {(args0Value.EndsWith("'") ? args0Value.Insert(args0Value.Length - 1, "%") : $"concat({args0Value}, '%')")}";
if (exp.Method.Name == "EndsWith") return $"({left}) LIKE {(args0Value.StartsWith("'") ? args0Value.Insert(1, "%") : $"concat('%', {args0Value})")}";
if (args0Value.StartsWith("'") && args0Value.EndsWith("'")) return $"({left}) LIKE {args0Value.Insert(1, "%").Insert(args0Value.Length, "%")}";
return $"({left}) LIKE concat('%', {args0Value}, '%')";
case "ToLower": return $"lower({left})";
@ -119,10 +135,10 @@ namespace FreeSql.MySql {
return left;
case "Replace": return $"replace({left}, {ExpressionLambdaToSql(exp.Arguments[0], _tables, _selectColumnMap, tbtype, isQuoteName)}, {ExpressionLambdaToSql(exp.Arguments[1], _tables, _selectColumnMap, tbtype, isQuoteName)})";
case "CompareTo": return $"strcmp({left}, {ExpressionLambdaToSql(exp.Arguments[0], _tables, _selectColumnMap, tbtype, isQuoteName)})";
case "Equals": return $"({left} = {ExpressionLambdaToSql(exp.Arguments[0], _tables, _selectColumnMap, tbtype, isQuoteName)})";
}
throw new Exception($"MySqlExpression 未现实函数表达式 {exp} 解析");
}
internal override string ExpressionLambdaToSqlCallMath(MethodCallExpression exp, List<SelectTableInfo> _tables, List<SelectColumnInfo> _selectColumnMap, SelectTableInfoType tbtype, bool isQuoteName) {
switch (exp.Method.Name) {
case "Abs": return $"abs({ExpressionLambdaToSql(exp.Arguments[0], _tables, _selectColumnMap, tbtype, isQuoteName)})";
@ -148,37 +164,77 @@ namespace FreeSql.MySql {
}
throw new Exception($"MySqlExpression 未现实函数表达式 {exp} 解析");
}
internal override string ExpressionLambdaToSqlCallDateTime(MethodCallExpression exp, List<SelectTableInfo> _tables, List<SelectColumnInfo> _selectColumnMap, SelectTableInfoType tbtype, bool isQuoteName) {
if (exp.Object == null) {
switch (exp.Method.Name) {
case "Compare": return $"(({ExpressionLambdaToSql(exp.Arguments[0], _tables, _selectColumnMap, tbtype, isQuoteName)}) - ({ExpressionLambdaToSql(exp.Arguments[1], _tables, _selectColumnMap, tbtype, isQuoteName)}))";
case "DaysInMonth": return $"dayofmonth(last_day(concat({ExpressionLambdaToSql(exp.Arguments[0], _tables, _selectColumnMap, tbtype, isQuoteName)}, '-', {ExpressionLambdaToSql(exp.Arguments[1], _tables, _selectColumnMap, tbtype, isQuoteName)}, '-01')))";
case "Equals": return $"({ExpressionLambdaToSql(exp.Arguments[0], _tables, _selectColumnMap, tbtype, isQuoteName)} = {ExpressionLambdaToSql(exp.Arguments[1], _tables, _selectColumnMap, tbtype, isQuoteName)})";
case "IsLeapYear":
var isLeapYearArgs1 = ExpressionLambdaToSql(exp.Arguments[0], _tables, _selectColumnMap, tbtype, isQuoteName);
return $"(({isLeapYearArgs1}) % 4 = 0 AND ({isLeapYearArgs1}) % 100 <> 0 OR ({isLeapYearArgs1}) % 400 = 0)";
case "Parse": return $"cast({ExpressionLambdaToSql(exp.Arguments[0], _tables, _selectColumnMap, tbtype, isQuoteName)} as datetime)";
case "ParseExact":
case "TryParse":
case "TryParseExact": return $"cast({ExpressionLambdaToSql(exp.Arguments[0], _tables, _selectColumnMap, tbtype, isQuoteName)} as datetime)";
}
return null;
}
var left = ExpressionLambdaToSql(exp.Object, _tables, _selectColumnMap, tbtype, isQuoteName);
var args1 = ExpressionLambdaToSql(exp.Arguments[0], _tables, _selectColumnMap, tbtype, isQuoteName);
var args1 = exp.Arguments.Count == 0 ? null : ExpressionLambdaToSql(exp.Arguments[0], _tables, _selectColumnMap, tbtype, isQuoteName);
switch (exp.Method.Name) {
case "Add": return $"date_add({left}, interval (time_to_sec({args1}) * 1000000 + extract(microsecond from {args1})) microsecond)";
case "AddDays": return $"date_add({left}, interval {args1} day)";
case "AddHours": return $"date_add({left}, interval {args1} hour)";
case "AddMilliseconds": return $"date_add({left}, interval {args1} microsecond)";
case "AddMinutes": return $"date_add({left}, interval {args1} minute)";
case "AddMonths": return $"date_add({left}, interval {args1} month)";
case "AddSeconds": return $"date_add({left}, interval {args1} second)";
case "Add": return $"date_add({left}, interval ({args1}) microsecond)";
case "AddDays": return $"date_add({left}, interval ({args1}) day)";
case "AddHours": return $"date_add({left}, interval ({args1}) hour)";
case "AddMilliseconds": return $"date_add({left}, interval ({args1}) * 1000 microsecond)";
case "AddMinutes": return $"date_add({left}, interval ({args1}) minute)";
case "AddMonths": return $"date_add({left}, interval ({args1}) month)";
case "AddSeconds": return $"date_add({left}, interval ({args1}) second)";
case "AddTicks": return $"date_add({left}, interval ({args1}) / 10 microsecond)";
case "AddYears": return $"date_add({left}, interval {args1} year)";
case "AddYears": return $"date_add({left}, interval ({args1}) year)";
case "Subtract":
if (exp.Arguments[0].Type.FullName == "System.DateTime" || exp.Arguments[0].Type.GenericTypeArguments.FirstOrDefault()?.FullName == "System.DateTime")
return $"({left} - {args1})";
return $"((time_to_sec({left}) - time_to_sec({args1})) * 1000000 + microsecond({left}) - microsecond({args1}))";
if (exp.Arguments[0].Type.FullName == "System.TimeSpan" || exp.Arguments[0].Type.GenericTypeArguments.FirstOrDefault()?.FullName == "System.TimeSpan")
return $"date_sub({left}, interval (time_to_sec({args1}) * 1000000 + extract(microsecond from {args1})) microsecond)";
return $"date_sub({left}, interval ({args1}) microsecond)";
break;
case "Equals": return $"({left} = {ExpressionLambdaToSql(exp.Arguments[0], _tables, _selectColumnMap, tbtype, isQuoteName)})";
case "CompareTo": return $"(({left}) - ({ExpressionLambdaToSql(exp.Arguments[0], _tables, _selectColumnMap, tbtype, isQuoteName)}))";
case "ToString": return $"date_format({left}, '%Y-%m-%d %H:%i:%s.%f')";
}
throw new Exception($"MySqlExpression 未现实函数表达式 {exp} 解析");
}
internal override string ExpressionLambdaToSqlCallTimeSpan(MethodCallExpression exp, List<SelectTableInfo> _tables, List<SelectColumnInfo> _selectColumnMap, SelectTableInfoType tbtype, bool isQuoteName) {
if (exp.Object == null) {
switch (exp.Method.Name) {
case "Compare": return $"(({ExpressionLambdaToSql(exp.Arguments[0], _tables, _selectColumnMap, tbtype, isQuoteName)}) - ({ExpressionLambdaToSql(exp.Arguments[1], _tables, _selectColumnMap, tbtype, isQuoteName)}))";
case "Equals": return $"({ExpressionLambdaToSql(exp.Arguments[0], _tables, _selectColumnMap, tbtype, isQuoteName)} = {ExpressionLambdaToSql(exp.Arguments[1], _tables, _selectColumnMap, tbtype, isQuoteName)})";
case "FromDays": return $"({ExpressionLambdaToSql(exp.Arguments[0], _tables, _selectColumnMap, tbtype, isQuoteName)} * {(long)1000000 * 60 * 60 * 24})";
case "FromHours": return $"({ExpressionLambdaToSql(exp.Arguments[0], _tables, _selectColumnMap, tbtype, isQuoteName)} * {(long)1000000 * 60 * 60})";
case "FromMilliseconds": return $"({ExpressionLambdaToSql(exp.Arguments[0], _tables, _selectColumnMap, tbtype, isQuoteName)} * 1000)";
case "FromMinutes": return $"({ExpressionLambdaToSql(exp.Arguments[0], _tables, _selectColumnMap, tbtype, isQuoteName)} * {(long)1000000 * 60})";
case "FromSeconds": return $"({ExpressionLambdaToSql(exp.Arguments[0], _tables, _selectColumnMap, tbtype, isQuoteName)} * 1000000)";
case "FromTicks": return $"({ExpressionLambdaToSql(exp.Arguments[0], _tables, _selectColumnMap, tbtype, isQuoteName)} / 10)";
case "Parse": return $"cast({ExpressionLambdaToSql(exp.Arguments[0], _tables, _selectColumnMap, tbtype, isQuoteName)} as signed)";
case "ParseExact":
case "TryParse":
case "TryParseExact": return $"cast({ExpressionLambdaToSql(exp.Arguments[0], _tables, _selectColumnMap, tbtype, isQuoteName)} as signed)";
}
return null;
}
var left = ExpressionLambdaToSql(exp.Object, _tables, _selectColumnMap, tbtype, isQuoteName);
var args1 = ExpressionLambdaToSql(exp.Arguments[0], _tables, _selectColumnMap, tbtype, isQuoteName);
var args1 = exp.Arguments.Count == 0 ? null : ExpressionLambdaToSql(exp.Arguments[0], _tables, _selectColumnMap, tbtype, isQuoteName);
switch (exp.Method.Name) {
case "Add": return $"(date_add('1970-1-1', interval (time_to_sec({left}) * 1000000 + extract(microsecond from {left}) + time_to_sec({args1}) * 1000000 + extract(microsecond from {args1})) microsecond)) microsecond) - date_add('1970-1-1', interval 0 microsecond) second))";
case "Subtract": return $"(date_add('1970-1-1', interval (time_to_sec({left}) * 1000000 + extract(microsecond from {left}) - time_to_sec({args1}) * 1000000 - extract(microsecond from {args1})) microsecond) - date_add('1970-1-1', interval 0 second))";
case "Add": return $"({left} + {args1})";
case "Subtract": return $"({left} - {args1})";
case "Equals": return $"({left} = {ExpressionLambdaToSql(exp.Arguments[0], _tables, _selectColumnMap, tbtype, isQuoteName)})";
case "CompareTo": return $"(({left}) - ({ExpressionLambdaToSql(exp.Arguments[0], _tables, _selectColumnMap, tbtype, isQuoteName)}))";
case "ToString": return $"date_format(date_add(cast('0001/1/1 0:00:00' as datetime), interval ({left}) microsecond), '%Y-%m-%d %H:%i:%s.%f')";
}
throw new Exception($"MySqlExpression 未现实函数表达式 {exp} 解析");
}
}
}

View File

@ -17,17 +17,14 @@ namespace FreeSql.PostgreSQL {
}
throw new Exception($"PostgreSQLExpression 未现实函数表达式 {exp} 解析");
}
internal override string ExpressionLambdaToSqlMemberAccessMath(MemberExpression exp, List<SelectTableInfo> _tables, List<SelectColumnInfo> _selectColumnMap, SelectTableInfoType tbtype, bool isQuoteName) {
var left = ExpressionLambdaToSql(exp.Expression, _tables, _selectColumnMap, tbtype, isQuoteName);
switch (exp.Member.Name) {
case "PI": return $"pi()";
}
throw new Exception($"PostgreSQLExpression 未现实函数表达式 {exp} 解析");
}
internal override string ExpressionLambdaToSqlMemberAccessDateTime(MemberExpression exp, List<SelectTableInfo> _tables, List<SelectColumnInfo> _selectColumnMap, SelectTableInfoType tbtype, bool isQuoteName) {
if (exp.Expression == null && exp.Member.Name == "Now") return "current_timestamp";
if (exp.Expression == null) {
switch (exp.Member.Name) {
case "Now": return "current_timestamp";
case "UtcNow": return "(current_timestamp at time zone 'UTC')";
case "Today": return "current_date";
}
}
var left = ExpressionLambdaToSql(exp.Expression, _tables, _selectColumnMap, tbtype, isQuoteName);
switch (exp.Member.Name) {
case "DayOfWeek": return $"extract(dow from ({left})::timestamp)";
@ -43,7 +40,6 @@ namespace FreeSql.PostgreSQL {
}
throw new Exception($"PostgreSQLExpression 未现实函数表达式 {exp} 解析");
}
internal override string ExpressionLambdaToSqlMemberAccessTimeSpan(MemberExpression exp, List<SelectTableInfo> _tables, List<SelectColumnInfo> _selectColumnMap, SelectTableInfoType tbtype, bool isQuoteName) {
var left = ExpressionLambdaToSql(exp.Expression, _tables, _selectColumnMap, tbtype, isQuoteName);
switch (exp.Member.Name) {
@ -61,6 +57,7 @@ namespace FreeSql.PostgreSQL {
}
throw new Exception($"PostgreSQLExpression 未现实函数表达式 {exp} 解析");
}
internal override string ExpressionLambdaToSqlCallString(MethodCallExpression exp, List<SelectTableInfo> _tables, List<SelectColumnInfo> _selectColumnMap, SelectTableInfoType tbtype, bool isQuoteName) {
var left = ExpressionLambdaToSql(exp.Object, _tables, _selectColumnMap, tbtype, isQuoteName);
switch (exp.Method.Name) {
@ -74,8 +71,8 @@ namespace FreeSql.PostgreSQL {
if (exp.Arguments[1].Type == typeof(bool) ||
exp.Arguments[1].Type == typeof(StringComparison) && ExpressionLambdaToSql(exp.Arguments[0], _tables, _selectColumnMap, tbtype, isQuoteName).Contains("IgnoreCase")) likeOpt = "ILIKE";
}
if (exp.Method.Name == "StartsWith") return $"({left}) {likeOpt} {(args0Value.StartsWith("'") ? args0Value.Insert(1, "%") : $"('%' || ({args0Value})::varchar)")}";
if (exp.Method.Name == "EndsWith") return $"({left}) {likeOpt} {(args0Value.EndsWith("'") ? args0Value.Insert(args0Value.Length - 1, "%") : $"(({args0Value})::varchar || '%')")}";
if (exp.Method.Name == "StartsWith") return $"({left}) {likeOpt} {(args0Value.EndsWith("'") ? args0Value.Insert(args0Value.Length - 1, "%") : $"(({args0Value})::varchar || '%')")}";
if (exp.Method.Name == "EndsWith") return $"({left}) {likeOpt} {(args0Value.StartsWith("'") ? args0Value.Insert(1, "%") : $"('%' || ({args0Value})::varchar)")}";
if (args0Value.StartsWith("'") && args0Value.EndsWith("'")) return $"({left}) {likeOpt} {args0Value.Insert(1, "%").Insert(args0Value.Length, "%")}";
return $"({left}) {likeOpt} ('%' || ({args0Value})::varchar || '%')";
case "ToLower": return $"lower({left})";
@ -123,7 +120,6 @@ namespace FreeSql.PostgreSQL {
}
throw new Exception($"PostgreSQLExpression 未现实函数表达式 {exp} 解析");
}
internal override string ExpressionLambdaToSqlCallMath(MethodCallExpression exp, List<SelectTableInfo> _tables, List<SelectColumnInfo> _selectColumnMap, SelectTableInfoType tbtype, bool isQuoteName) {
switch (exp.Method.Name) {
case "Abs": return $"abs({ExpressionLambdaToSql(exp.Arguments[0], _tables, _selectColumnMap, tbtype, isQuoteName)})";
@ -149,7 +145,6 @@ namespace FreeSql.PostgreSQL {
}
throw new Exception($"PostgreSQLExpression 未现实函数表达式 {exp} 解析");
}
internal override string ExpressionLambdaToSqlCallDateTime(MethodCallExpression exp, List<SelectTableInfo> _tables, List<SelectColumnInfo> _selectColumnMap, SelectTableInfoType tbtype, bool isQuoteName) {
var left = ExpressionLambdaToSql(exp.Object, _tables, _selectColumnMap, tbtype, isQuoteName);
var args1 = ExpressionLambdaToSql(exp.Arguments[0], _tables, _selectColumnMap, tbtype, isQuoteName);

View File

@ -11,23 +11,27 @@ namespace FreeSql.SqlServer {
public SqlServerExpression(CommonUtils common) : base(common) { }
internal override string ExpressionLambdaToSqlMemberAccessString(MemberExpression exp, List<SelectTableInfo> _tables, List<SelectColumnInfo> _selectColumnMap, SelectTableInfoType tbtype, bool isQuoteName) {
if (exp.Expression == null) {
switch (exp.Member.Name) {
case "Empty": return "''";
}
return null;
}
var left = ExpressionLambdaToSql(exp.Expression, _tables, _selectColumnMap, tbtype, isQuoteName);
switch (exp.Member.Name) {
case "Length": return $"len({left})";
}
throw new Exception($"SqlServerExpression 未现实函数表达式 {exp} 解析");
}
internal override string ExpressionLambdaToSqlMemberAccessMath(MemberExpression exp, List<SelectTableInfo> _tables, List<SelectColumnInfo> _selectColumnMap, SelectTableInfoType tbtype, bool isQuoteName) {
var left = ExpressionLambdaToSql(exp.Expression, _tables, _selectColumnMap, tbtype, isQuoteName);
switch (exp.Member.Name) {
case "PI": return $"pi()";
}
throw new Exception($"SqlServerExpression 未现实函数表达式 {exp} 解析");
}
internal override string ExpressionLambdaToSqlMemberAccessDateTime(MemberExpression exp, List<SelectTableInfo> _tables, List<SelectColumnInfo> _selectColumnMap, SelectTableInfoType tbtype, bool isQuoteName) {
if (exp.Expression == null && exp.Member.Name == "Now") return "getdate()";
if (exp.Expression == null) {
switch (exp.Member.Name) {
case "Now": return "getdate()";
case "UtcNow": return "getutcdate()";
case "Today": return "cast(convert(char(10),getdate(),120) as date)()";
}
return null;
}
var left = ExpressionLambdaToSql(exp.Expression, _tables, _selectColumnMap, tbtype, isQuoteName);
switch (exp.Member.Name) {
case "DayOfWeek": return $"(datepart(weekday, {left}) - 1)";
@ -43,7 +47,6 @@ namespace FreeSql.SqlServer {
}
throw new Exception($"SqlServerExpression 未现实函数表达式 {exp} 解析");
}
internal override string ExpressionLambdaToSqlMemberAccessTimeSpan(MemberExpression exp, List<SelectTableInfo> _tables, List<SelectColumnInfo> _selectColumnMap, SelectTableInfoType tbtype, bool isQuoteName) {
var left = ExpressionLambdaToSql(exp.Expression, _tables, _selectColumnMap, tbtype, isQuoteName);
switch (exp.Member.Name) {
@ -61,6 +64,7 @@ namespace FreeSql.SqlServer {
}
throw new Exception($"SqlServerExpression 未现实函数表达式 {exp} 解析");
}
internal override string ExpressionLambdaToSqlCallString(MethodCallExpression exp, List<SelectTableInfo> _tables, List<SelectColumnInfo> _selectColumnMap, SelectTableInfoType tbtype, bool isQuoteName) {
var left = ExpressionLambdaToSql(exp.Object, _tables, _selectColumnMap, tbtype, isQuoteName);
switch (exp.Method.Name) {
@ -69,8 +73,8 @@ namespace FreeSql.SqlServer {
case "Contains":
var args0Value = ExpressionLambdaToSql(exp.Arguments[0], _tables, _selectColumnMap, tbtype, isQuoteName);
if (args0Value == "NULL") return $"({left}) IS NULL";
if (exp.Method.Name == "StartsWith") return $"({left}) LIKE {(args0Value.StartsWith("'") ? args0Value.Insert(1, "%") : $"('%' + cast({args0Value} as nvarchar))")}";
if (exp.Method.Name == "EndsWith") return $"({left}) LIKE {(args0Value.EndsWith("'") ? args0Value.Insert(args0Value.Length - 1, "%") : $"(cast({args0Value} as nvarchar) + '%')")}";
if (exp.Method.Name == "StartsWith") return $"({left}) LIKE {(args0Value.EndsWith("'") ? args0Value.Insert(args0Value.Length - 1, "%") : $"(cast({args0Value} as nvarchar) + '%')")}";
if (exp.Method.Name == "EndsWith") return $"({left}) LIKE {(args0Value.StartsWith("'") ? args0Value.Insert(1, "%") : $"('%' + cast({args0Value} as nvarchar))")}";
if (args0Value.StartsWith("'") && args0Value.EndsWith("'")) return $"({left}) LIKE {args0Value.Insert(1, "%").Insert(args0Value.Length, "%")}";
return $"({left}) LIKE ('%' + cast({args0Value} as nvarchar) + '%')";
case "ToLower": return $"lower({left})";
@ -99,7 +103,6 @@ namespace FreeSql.SqlServer {
}
throw new Exception($"SqlServerExpression 未现实函数表达式 {exp} 解析");
}
internal override string ExpressionLambdaToSqlCallMath(MethodCallExpression exp, List<SelectTableInfo> _tables, List<SelectColumnInfo> _selectColumnMap, SelectTableInfoType tbtype, bool isQuoteName) {
switch (exp.Method.Name) {
case "Abs": return $"abs({ExpressionLambdaToSql(exp.Arguments[0], _tables, _selectColumnMap, tbtype, isQuoteName)})";
@ -125,7 +128,6 @@ namespace FreeSql.SqlServer {
}
throw new Exception($"SqlServerExpression 未现实函数表达式 {exp} 解析");
}
internal override string ExpressionLambdaToSqlCallDateTime(MethodCallExpression exp, List<SelectTableInfo> _tables, List<SelectColumnInfo> _selectColumnMap, SelectTableInfoType tbtype, bool isQuoteName) {
var left = ExpressionLambdaToSql(exp.Object, _tables, _selectColumnMap, tbtype, isQuoteName);
var args1 = ExpressionLambdaToSql(exp.Arguments[0], _tables, _selectColumnMap, tbtype, isQuoteName);