mirror of
				https://github.com/nsnail/FreeSql.git
				synced 2025-11-04 09:15:27 +08:00 
			
		
		
		
	增加 int.Parse Guid.Parse 系列转换、Guid.NewGuid、new Random.NextDouble 等表达式函数解析
This commit is contained in:
		@@ -215,7 +215,10 @@ namespace FreeSql.Internal {
 | 
			
		||||
				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.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:
 | 
			
		||||
					var othercExp = ExpressionLambdaToSqlOther(exp, _tables, _selectColumnMap, getSelectGroupingMapString, tbtype, isQuoteName);
 | 
			
		||||
					if (string.IsNullOrEmpty(othercExp) == false) return othercExp;
 | 
			
		||||
					return ExpressionLambdaToSql((exp as UnaryExpression)?.Operand, _tables, _selectColumnMap, getSelectGroupingMapString, tbtype, isQuoteName);
 | 
			
		||||
				case ExpressionType.Negate:
 | 
			
		||||
				case ExpressionType.NegateChecked: return "-" + ExpressionLambdaToSql((exp as UnaryExpression)?.Operand, _tables, _selectColumnMap, getSelectGroupingMapString, tbtype, isQuoteName);
 | 
			
		||||
				case ExpressionType.Constant: return _common.FormatSql("{0}", (exp as ConstantExpression)?.Value);
 | 
			
		||||
@@ -461,7 +464,7 @@ namespace FreeSql.Internal {
 | 
			
		||||
					MethodCallExpression callExp = null;
 | 
			
		||||
					var exp2 = exp4.Expression;
 | 
			
		||||
					while (true) {
 | 
			
		||||
						switch(exp2.NodeType) {
 | 
			
		||||
						switch(exp2?.NodeType) {
 | 
			
		||||
							case ExpressionType.Constant:
 | 
			
		||||
								expStack.Push(exp2);
 | 
			
		||||
								break;
 | 
			
		||||
@@ -514,6 +517,10 @@ namespace FreeSql.Internal {
 | 
			
		||||
								finds = _tables.Where(a2 => (isa && a2.Parameter != null || !isa && a2.Parameter == null) &&
 | 
			
		||||
									a2.Table.Type == tbtmp.Type && a2.Alias == alias && a2.Alias.StartsWith($"{navdot[0].Alias}__") &&
 | 
			
		||||
									(isthis && a2.Type != SelectTableInfoType.Parent || !isthis && a2.Type == SelectTableInfoType.Parent)).ToArray();
 | 
			
		||||
								if (finds.Length == 0)
 | 
			
		||||
									finds = _tables.Where(a2 => 
 | 
			
		||||
										 a2.Table.Type == tbtmp.Type && a2.Alias == alias && a2.Alias.StartsWith($"{navdot[0].Alias}__") &&
 | 
			
		||||
										 (isthis && a2.Type != SelectTableInfoType.Parent || !isthis && a2.Type == SelectTableInfoType.Parent)).ToArray();
 | 
			
		||||
							} else {
 | 
			
		||||
								finds = _tables.Where(a2 => (isa && a2.Parameter != null || isa && a2.Parameter == null) &&
 | 
			
		||||
									a2.Table.Type == tbtmp.Type && a2.Alias == alias).ToArray();
 | 
			
		||||
 
 | 
			
		||||
@@ -15,8 +15,67 @@ namespace FreeSql.MySql {
 | 
			
		||||
		internal override string ExpressionLambdaToSqlOther(Expression exp, List<SelectTableInfo> _tables, List<SelectColumnInfo> _selectColumnMap, Func<Expression[], string> getSelectGroupingMapString, SelectTableInfoType tbtype, bool isQuoteName) {
 | 
			
		||||
			Func<Expression, string> getExp = exparg => ExpressionLambdaToSql(exparg, _tables, _selectColumnMap, getSelectGroupingMapString, tbtype, isQuoteName);
 | 
			
		||||
			switch (exp.NodeType) {
 | 
			
		||||
				case ExpressionType.Convert:
 | 
			
		||||
					var operandExp = (exp as UnaryExpression)?.Operand;
 | 
			
		||||
					switch (exp.Type.NullableTypeOrThis().ToString()) {
 | 
			
		||||
						case "System.Boolean": return $"({getExp(operandExp)} not in ('0','false'))";
 | 
			
		||||
						case "System.Byte": return $"cast({getExp(operandExp)} as unsigned)";
 | 
			
		||||
						case "System.Char": return $"substr(cast({getExp(operandExp)} as char), 1, 1)";
 | 
			
		||||
						case "System.DateTime": return $"cast({getExp(operandExp)} as datetime)";
 | 
			
		||||
						case "System.Decimal": return $"cast({getExp(operandExp)} as decimal(36,18))";
 | 
			
		||||
						case "System.Double": return $"cast({getExp(operandExp)} as decimal(32,16))";
 | 
			
		||||
						case "System.Int16":
 | 
			
		||||
						case "System.Int32":
 | 
			
		||||
						case "System.Int64":
 | 
			
		||||
						case "System.SByte": return $"cast({getExp(operandExp)} as signed)";
 | 
			
		||||
						case "System.Single": return $"cast({getExp(operandExp)} as decimal(14,7))";
 | 
			
		||||
						case "System.String": return $"cast({getExp(operandExp)} as char)";
 | 
			
		||||
						case "System.UInt16":
 | 
			
		||||
						case "System.UInt32":
 | 
			
		||||
						case "System.UInt64": return $"cast({getExp(operandExp)} as unsigned)";
 | 
			
		||||
						case "System.Guid": return $"substr(cast({getExp(operandExp)} as char), 1, 36)";
 | 
			
		||||
					}
 | 
			
		||||
					break;
 | 
			
		||||
				case ExpressionType.Call:
 | 
			
		||||
					var callExp = exp as MethodCallExpression;
 | 
			
		||||
 | 
			
		||||
					switch (callExp.Method.Name) {
 | 
			
		||||
						case "Parse":
 | 
			
		||||
						case "TryParse":
 | 
			
		||||
							switch (callExp.Method.DeclaringType.NullableTypeOrThis().ToString()) {
 | 
			
		||||
								case "System.Boolean": return $"({getExp(callExp.Arguments[0])} not in ('0','false'))";
 | 
			
		||||
								case "System.Byte": return $"cast({getExp(callExp.Arguments[0])} as unsigned)";
 | 
			
		||||
								case "System.Char": return $"substr(cast({getExp(callExp.Arguments[0])} as char), 1, 1)";
 | 
			
		||||
								case "System.DateTime": return $"cast({getExp(callExp.Arguments[0])} as datetime)";
 | 
			
		||||
								case "System.Decimal": return $"cast({getExp(callExp.Arguments[0])} as decimal(36,18))";
 | 
			
		||||
								case "System.Double": return $"cast({getExp(callExp.Arguments[0])} as decimal(32,16))";
 | 
			
		||||
								case "System.Int16":
 | 
			
		||||
								case "System.Int32":
 | 
			
		||||
								case "System.Int64":
 | 
			
		||||
								case "System.SByte": return $"cast({getExp(callExp.Arguments[0])} as signed)";
 | 
			
		||||
								case "System.Single": return $"cast({getExp(callExp.Arguments[0])} as decimal(14,7))";
 | 
			
		||||
								case "System.UInt16":
 | 
			
		||||
								case "System.UInt32":
 | 
			
		||||
								case "System.UInt64": return $"cast({getExp(callExp.Arguments[0])} as unsigned)";
 | 
			
		||||
								case "System.Guid": return $"substr(cast({getExp(callExp.Arguments[0])} as char), 1, 36)";
 | 
			
		||||
							}
 | 
			
		||||
							break;
 | 
			
		||||
						case "NewGuid":
 | 
			
		||||
							break;
 | 
			
		||||
						case "Next":
 | 
			
		||||
							if (callExp.Object?.Type == typeof(Random)) return "cast(rand()*1000000000 as signed)";
 | 
			
		||||
							break;
 | 
			
		||||
						case "NextDouble":
 | 
			
		||||
							if (callExp.Object?.Type == typeof(Random)) return "rand()";
 | 
			
		||||
							break;
 | 
			
		||||
						case "Random":
 | 
			
		||||
							if (callExp.Method.DeclaringType.IsNumberType()) return "rand()";
 | 
			
		||||
							break;
 | 
			
		||||
						case "ToString":
 | 
			
		||||
							if (callExp.Object != null) return $"cast({getExp(callExp.Object)} as char)";
 | 
			
		||||
							break;
 | 
			
		||||
					}
 | 
			
		||||
 | 
			
		||||
					var objExp = callExp.Object;
 | 
			
		||||
					var objType = objExp?.Type;
 | 
			
		||||
					if (objType?.FullName == "System.Byte[]") return null;
 | 
			
		||||
 
 | 
			
		||||
@@ -15,8 +15,67 @@ namespace FreeSql.Oracle {
 | 
			
		||||
		internal override string ExpressionLambdaToSqlOther(Expression exp, List<SelectTableInfo> _tables, List<SelectColumnInfo> _selectColumnMap, Func<Expression[], string> getSelectGroupingMapString, SelectTableInfoType tbtype, bool isQuoteName) {
 | 
			
		||||
			Func<Expression, string> getExp = exparg => ExpressionLambdaToSql(exparg, _tables, _selectColumnMap, getSelectGroupingMapString, tbtype, isQuoteName);
 | 
			
		||||
			switch (exp.NodeType) {
 | 
			
		||||
				case ExpressionType.Convert:
 | 
			
		||||
					var operandExp = (exp as UnaryExpression)?.Operand;
 | 
			
		||||
					switch (exp.Type.NullableTypeOrThis().ToString()) {
 | 
			
		||||
						//case "System.Boolean": return $"({getExp(operandExp)} not in ('0','false'))";
 | 
			
		||||
						case "System.Byte": return $"cast({getExp(operandExp)} as number)";
 | 
			
		||||
						case "System.Char": return $"substr(to_char({getExp(operandExp)}), 1, 1)";
 | 
			
		||||
						case "System.DateTime": return $"to_timestamp({getExp(operandExp)},'YYYY-MM-DD HH24:MI:SS.FF6')";
 | 
			
		||||
						case "System.Decimal": return $"cast({getExp(operandExp)} as number)";
 | 
			
		||||
						case "System.Double": return $"cast({getExp(operandExp)} as number)";
 | 
			
		||||
						case "System.Int16":
 | 
			
		||||
						case "System.Int32":
 | 
			
		||||
						case "System.Int64":
 | 
			
		||||
						case "System.SByte": return $"cast({getExp(operandExp)} as number)";
 | 
			
		||||
						case "System.Single": return $"cast({getExp(operandExp)} as number)";
 | 
			
		||||
						case "System.String": return $"to_char({getExp(operandExp)})";
 | 
			
		||||
						case "System.UInt16":
 | 
			
		||||
						case "System.UInt32":
 | 
			
		||||
						case "System.UInt64": return $"cast({getExp(operandExp)} as number)";
 | 
			
		||||
						case "System.Guid": return $"substr(to_char({getExp(operandExp)}), 1, 36)";
 | 
			
		||||
					}
 | 
			
		||||
					break;
 | 
			
		||||
				case ExpressionType.Call:
 | 
			
		||||
					var callExp = exp as MethodCallExpression;
 | 
			
		||||
 | 
			
		||||
					switch (callExp.Method.Name) {
 | 
			
		||||
						case "Parse":
 | 
			
		||||
						case "TryParse":
 | 
			
		||||
							switch (callExp.Method.DeclaringType.NullableTypeOrThis().ToString()) {
 | 
			
		||||
								//case "System.Boolean": return $"({getExp(callExp.Arguments[0])} not in ('0','false'))";
 | 
			
		||||
								case "System.Byte": return $"cast({getExp(callExp.Arguments[0])} as number)";
 | 
			
		||||
								case "System.Char": return $"substr(to_char({getExp(callExp.Arguments[0])}), 1, 1)";
 | 
			
		||||
								case "System.DateTime": return $"to_timestamp({getExp(callExp.Arguments[0])},'YYYY-MM-DD HH24:MI:SS.FF6')";
 | 
			
		||||
								case "System.Decimal": return $"cast({getExp(callExp.Arguments[0])} as number)";
 | 
			
		||||
								case "System.Double": return $"cast({getExp(callExp.Arguments[0])} as number)";
 | 
			
		||||
								case "System.Int16":
 | 
			
		||||
								case "System.Int32":
 | 
			
		||||
								case "System.Int64":
 | 
			
		||||
								case "System.SByte": return $"cast({getExp(callExp.Arguments[0])} as number)";
 | 
			
		||||
								case "System.Single": return $"cast({getExp(callExp.Arguments[0])} as number)";
 | 
			
		||||
								case "System.UInt16":
 | 
			
		||||
								case "System.UInt32":
 | 
			
		||||
								case "System.UInt64": return $"cast({getExp(callExp.Arguments[0])} as number)";
 | 
			
		||||
								case "System.Guid": return $"substr(to_char({getExp(callExp.Arguments[0])}), 1, 36)";
 | 
			
		||||
							}
 | 
			
		||||
							break;
 | 
			
		||||
						case "NewGuid":
 | 
			
		||||
							break;
 | 
			
		||||
						case "Next":
 | 
			
		||||
							if (callExp.Object?.Type == typeof(Random)) return "cast(dbms_random.value*1000000000 as smallint)";
 | 
			
		||||
							break;
 | 
			
		||||
						case "NextDouble":
 | 
			
		||||
							if (callExp.Object?.Type == typeof(Random)) return "dbms_random.value";
 | 
			
		||||
							break;
 | 
			
		||||
						case "Random":
 | 
			
		||||
							if (callExp.Method.DeclaringType.IsNumberType()) return "dbms_random.value";
 | 
			
		||||
							break;
 | 
			
		||||
						case "ToString":
 | 
			
		||||
							if (callExp.Object != null) return $"to_char({getExp(callExp.Object)})";
 | 
			
		||||
							break;
 | 
			
		||||
					}
 | 
			
		||||
 | 
			
		||||
					var objExp = callExp.Object;
 | 
			
		||||
					var objType = objExp?.Type;
 | 
			
		||||
					if (objType?.FullName == "System.Byte[]") return null;
 | 
			
		||||
 
 | 
			
		||||
@@ -16,12 +16,71 @@ namespace FreeSql.PostgreSQL {
 | 
			
		||||
		internal override string ExpressionLambdaToSqlOther(Expression exp, List<SelectTableInfo> _tables, List<SelectColumnInfo> _selectColumnMap, Func<Expression[], string> getSelectGroupingMapString, SelectTableInfoType tbtype, bool isQuoteName) {
 | 
			
		||||
			Func<Expression, string> getExp = exparg => ExpressionLambdaToSql(exparg, _tables, _selectColumnMap, getSelectGroupingMapString, tbtype, isQuoteName);
 | 
			
		||||
			switch (exp.NodeType) {
 | 
			
		||||
				case ExpressionType.Convert:
 | 
			
		||||
					var operandExp = (exp as UnaryExpression)?.Operand;
 | 
			
		||||
					switch (exp.Type.NullableTypeOrThis().ToString()) {
 | 
			
		||||
						case "System.Boolean": return $"(({getExp(operandExp)})::varchar not in ('0','false','f','no'))";
 | 
			
		||||
						case "System.Byte": return $"({getExp(operandExp)})::int2";
 | 
			
		||||
						case "System.Char": return $"substr(({getExp(operandExp)})::char, 1, 1)";
 | 
			
		||||
						case "System.DateTime": return $"({getExp(operandExp)})::timestamp";
 | 
			
		||||
						case "System.Decimal": return $"({getExp(operandExp)})::numeric";
 | 
			
		||||
						case "System.Double": return $"({getExp(operandExp)})::float8";
 | 
			
		||||
						case "System.Int16": return $"({getExp(operandExp)})::int2";
 | 
			
		||||
						case "System.Int32": return $"({getExp(operandExp)})::int4";
 | 
			
		||||
						case "System.Int64": return $"({getExp(operandExp)})::int8";
 | 
			
		||||
						case "System.SByte": return $"({getExp(operandExp)})::int2";
 | 
			
		||||
						case "System.Single": return $"({getExp(operandExp)})::float4";
 | 
			
		||||
						case "System.String": return $"({getExp(operandExp)})::varchar";
 | 
			
		||||
						case "System.UInt16": return $"({getExp(operandExp)})::int2";
 | 
			
		||||
						case "System.UInt32": return $"({getExp(operandExp)})::int4";
 | 
			
		||||
						case "System.UInt64": return $"({getExp(operandExp)})::int8";
 | 
			
		||||
						case "System.Guid": return $"({getExp(operandExp)})::uuid";
 | 
			
		||||
					}
 | 
			
		||||
					break;
 | 
			
		||||
				case ExpressionType.ArrayLength:
 | 
			
		||||
					var arrOperExp = getExp((exp as UnaryExpression).Operand);
 | 
			
		||||
					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";
 | 
			
		||||
				case ExpressionType.Call:
 | 
			
		||||
					var callExp = exp as MethodCallExpression;
 | 
			
		||||
 | 
			
		||||
					switch (callExp.Method.Name) {
 | 
			
		||||
						case "Parse":
 | 
			
		||||
						case "TryParse":
 | 
			
		||||
							switch (callExp.Method.DeclaringType.NullableTypeOrThis().ToString()) {
 | 
			
		||||
								case "System.Boolean": return $"(({getExp(callExp.Arguments[0])})::varchar not in ('0','false','f','no'))";
 | 
			
		||||
								case "System.Byte": return $"({getExp(callExp.Arguments[0])})::int2";
 | 
			
		||||
								case "System.Char": return $"substr(({getExp(callExp.Arguments[0])})::char, 1, 1)";
 | 
			
		||||
								case "System.DateTime": return $"({getExp(callExp.Arguments[0])})::timestamp";
 | 
			
		||||
								case "System.Decimal": return $"({getExp(callExp.Arguments[0])})::numeric";
 | 
			
		||||
								case "System.Double": return $"({getExp(callExp.Arguments[0])})::float8";
 | 
			
		||||
								case "System.Int16": return $"({getExp(callExp.Arguments[0])})::int2";
 | 
			
		||||
								case "System.Int32": return $"({getExp(callExp.Arguments[0])})::int4";
 | 
			
		||||
								case "System.Int64": return $"({getExp(callExp.Arguments[0])})::int8";
 | 
			
		||||
								case "System.SByte": return $"({getExp(callExp.Arguments[0])})::int2";
 | 
			
		||||
								case "System.Single": return $"({getExp(callExp.Arguments[0])})::float4";
 | 
			
		||||
								case "System.UInt16": return $"({getExp(callExp.Arguments[0])})::int2";
 | 
			
		||||
								case "System.UInt32": return $"({getExp(callExp.Arguments[0])})::int4";
 | 
			
		||||
								case "System.UInt64": return $"({getExp(callExp.Arguments[0])})::int8";
 | 
			
		||||
								case "System.Guid": return $"({getExp(callExp.Arguments[0])})::uuid";
 | 
			
		||||
							}
 | 
			
		||||
							break;
 | 
			
		||||
						case "NewGuid":
 | 
			
		||||
							break;
 | 
			
		||||
						case "Next":
 | 
			
		||||
							if (callExp.Object?.Type == typeof(Random)) return "(random()*1000000000)::int4";
 | 
			
		||||
							break;
 | 
			
		||||
						case "NextDouble":
 | 
			
		||||
							if (callExp.Object?.Type == typeof(Random)) return "random()";
 | 
			
		||||
							break;
 | 
			
		||||
						case "Random":
 | 
			
		||||
							if (callExp.Method.DeclaringType.IsNumberType()) return "random()";
 | 
			
		||||
							break;
 | 
			
		||||
						case "ToString":
 | 
			
		||||
							if (callExp.Object != null) return $"({getExp(callExp.Object)})::varchar";
 | 
			
		||||
							break;
 | 
			
		||||
					}
 | 
			
		||||
 | 
			
		||||
					var objExp = callExp.Object;
 | 
			
		||||
					var objType = objExp?.Type;
 | 
			
		||||
					if (objType?.FullName == "System.Byte[]") return null;
 | 
			
		||||
 
 | 
			
		||||
@@ -15,8 +15,70 @@ namespace FreeSql.SqlServer {
 | 
			
		||||
		internal override string ExpressionLambdaToSqlOther(Expression exp, List<SelectTableInfo> _tables, List<SelectColumnInfo> _selectColumnMap, Func<Expression[], string> getSelectGroupingMapString, SelectTableInfoType tbtype, bool isQuoteName) {
 | 
			
		||||
			Func<Expression, string> getExp = exparg => ExpressionLambdaToSql(exparg, _tables, _selectColumnMap, getSelectGroupingMapString, tbtype, isQuoteName);
 | 
			
		||||
			switch (exp.NodeType) {
 | 
			
		||||
				case ExpressionType.Convert:
 | 
			
		||||
					var operandExp = (exp as UnaryExpression)?.Operand;
 | 
			
		||||
					switch (exp.Type.NullableTypeOrThis().ToString()) {
 | 
			
		||||
						case "System.Boolean": return $"(cast({getExp(operandExp)} as varchar) not in ('0','false'))";
 | 
			
		||||
						case "System.Byte": return $"cast({getExp(operandExp)} as tinyint)";
 | 
			
		||||
						case "System.Char": return $"substring(cast({getExp(operandExp)} as nvarchar),1,1)";
 | 
			
		||||
						case "System.DateTime": return $"cast({getExp(operandExp)} as datetime)";
 | 
			
		||||
						case "System.Decimal": return $"cast({getExp(operandExp)} as decimal(36,18))";
 | 
			
		||||
						case "System.Double": return $"cast({getExp(operandExp)} as decimal(32,16))";
 | 
			
		||||
						case "System.Int16": return $"cast({getExp(operandExp)} as smallint)";
 | 
			
		||||
						case "System.Int32": return $"cast({getExp(operandExp)} as int)";
 | 
			
		||||
						case "System.Int64": return $"cast({getExp(operandExp)} as bigint)";
 | 
			
		||||
						case "System.SByte": return $"cast({getExp(operandExp)} as tinyint)";
 | 
			
		||||
						case "System.Single": return $"cast({getExp(operandExp)} as decimal(14,7))";
 | 
			
		||||
						case "System.String": return operandExp.Type.NullableTypeOrThis() == typeof(Guid) ? $"cast({getExp(operandExp)} as varchar(36))" : $"cast({getExp(operandExp)} as nvarchar)";
 | 
			
		||||
						case "System.UInt16": return $"cast({getExp(operandExp)} as smallint)";
 | 
			
		||||
						case "System.UInt32": return $"cast({getExp(operandExp)} as int)";
 | 
			
		||||
						case "System.UInt64": return $"cast({getExp(operandExp)} as bigint)";
 | 
			
		||||
						case "System.Guid": return $"cast({getExp(operandExp)} as uniqueidentifier)";
 | 
			
		||||
					}
 | 
			
		||||
					break;
 | 
			
		||||
				case ExpressionType.Call:
 | 
			
		||||
					var callExp = exp as MethodCallExpression;
 | 
			
		||||
 | 
			
		||||
					switch(callExp.Method.Name) {
 | 
			
		||||
						case "Parse":
 | 
			
		||||
						case "TryParse":
 | 
			
		||||
							switch (callExp.Method.DeclaringType.NullableTypeOrThis().ToString()) {
 | 
			
		||||
								case "System.Boolean": return $"(cast({getExp(callExp.Arguments[0])} as varchar) not in ('0','false'))";
 | 
			
		||||
								case "System.Byte": return $"cast({getExp(callExp.Arguments[0])} as tinyint)";
 | 
			
		||||
								case "System.Char": return $"substring(cast({getExp(callExp.Arguments[0])} as nvarchar),1,1)";
 | 
			
		||||
								case "System.DateTime": return $"cast({getExp(callExp.Arguments[0])} as datetime)";
 | 
			
		||||
								case "System.Decimal": return $"cast({getExp(callExp.Arguments[0])} as decimal(36,18))";
 | 
			
		||||
								case "System.Double": return $"cast({getExp(callExp.Arguments[0])} as decimal(32,16))";
 | 
			
		||||
								case "System.Int16": return $"cast({getExp(callExp.Arguments[0])} as smallint)";
 | 
			
		||||
								case "System.Int32": return $"cast({getExp(callExp.Arguments[0])} as int)";
 | 
			
		||||
								case "System.Int64": return $"cast({getExp(callExp.Arguments[0])} as bigint)";
 | 
			
		||||
								case "System.SByte": return $"cast({getExp(callExp.Arguments[0])} as tinyint)";
 | 
			
		||||
								case "System.Single": return $"cast({getExp(callExp.Arguments[0])} as decimal(14,7))";
 | 
			
		||||
								case "System.UInt16": return $"cast({getExp(callExp.Arguments[0])} as smallint)";
 | 
			
		||||
								case "System.UInt32": return $"cast({getExp(callExp.Arguments[0])} as int)";
 | 
			
		||||
								case "System.UInt64": return $"cast({getExp(callExp.Arguments[0])} as bigint)";
 | 
			
		||||
								case "System.Guid": return $"cast({getExp(callExp.Arguments[0])} as uniqueidentifier)";
 | 
			
		||||
							}
 | 
			
		||||
							break;
 | 
			
		||||
						case "NewGuid":
 | 
			
		||||
							switch (callExp.Method.DeclaringType.NullableTypeOrThis().ToString()) {
 | 
			
		||||
								case "System.Guid": return $"newid()";
 | 
			
		||||
							}
 | 
			
		||||
							break;
 | 
			
		||||
						case "Next":
 | 
			
		||||
							if (callExp.Object?.Type == typeof(Random)) return "cast(rand()*1000000000 as int)";
 | 
			
		||||
							break;
 | 
			
		||||
						case "NextDouble":
 | 
			
		||||
							if (callExp.Object?.Type == typeof(Random)) return "rand()";
 | 
			
		||||
							break;
 | 
			
		||||
						case "Random":
 | 
			
		||||
							if (callExp.Method.DeclaringType.IsNumberType()) return "rand()";
 | 
			
		||||
							break;
 | 
			
		||||
						case "ToString":
 | 
			
		||||
							if (callExp.Object != null) return callExp.Object.Type.NullableTypeOrThis() == typeof(Guid) ? $"cast({getExp(callExp.Object)} as varchar(36))" : $"cast({getExp(callExp.Object)} as nvarchar)";
 | 
			
		||||
							break;
 | 
			
		||||
					}
 | 
			
		||||
 | 
			
		||||
					var objExp = callExp.Object;
 | 
			
		||||
					var objType = objExp?.Type;
 | 
			
		||||
					if (objType?.FullName == "System.Byte[]") return null;
 | 
			
		||||
@@ -306,7 +368,7 @@ namespace FreeSql.SqlServer {
 | 
			
		||||
					case "ToInt64": return $"cast({getExp(exp.Arguments[0])} as bigint)";
 | 
			
		||||
					case "ToSByte": return $"cast({getExp(exp.Arguments[0])} as tinyint)";
 | 
			
		||||
					case "ToSingle": return $"cast({getExp(exp.Arguments[0])} as decimal(14,7))";
 | 
			
		||||
					case "ToString": return $"cast({getExp(exp.Arguments[0])} as nvarchar)";
 | 
			
		||||
					case "ToString": return exp.Arguments[0].Type.NullableTypeOrThis() == typeof(Guid) ? $"cast({getExp(exp.Arguments[0])} as varchar(36))" : $"cast({getExp(exp.Arguments[0])} as nvarchar)";
 | 
			
		||||
					case "ToUInt16": return $"cast({getExp(exp.Arguments[0])} as smallint)";
 | 
			
		||||
					case "ToUInt32": return $"cast({getExp(exp.Arguments[0])} as int)";
 | 
			
		||||
					case "ToUInt64": return $"cast({getExp(exp.Arguments[0])} as bigint)";
 | 
			
		||||
 
 | 
			
		||||
@@ -15,8 +15,67 @@ namespace FreeSql.Sqlite {
 | 
			
		||||
		internal override string ExpressionLambdaToSqlOther(Expression exp, List<SelectTableInfo> _tables, List<SelectColumnInfo> _selectColumnMap, Func<Expression[], string> getSelectGroupingMapString, SelectTableInfoType tbtype, bool isQuoteName) {
 | 
			
		||||
			Func<Expression, string> getExp = exparg => ExpressionLambdaToSql(exparg, _tables, _selectColumnMap, getSelectGroupingMapString, tbtype, isQuoteName);
 | 
			
		||||
			switch (exp.NodeType) {
 | 
			
		||||
				case ExpressionType.Convert:
 | 
			
		||||
					var operandExp = (exp as UnaryExpression)?.Operand;
 | 
			
		||||
					switch (exp.Type.NullableTypeOrThis().ToString()) {
 | 
			
		||||
						case "System.Boolean": return $"({getExp(operandExp)} not in ('0','false'))";
 | 
			
		||||
						case "System.Byte": return $"cast({getExp(operandExp)} as int2)";
 | 
			
		||||
						case "System.Char": return $"substr(cast({getExp(operandExp)} as character), 1, 1)";
 | 
			
		||||
						case "System.DateTime": return $"datetime({getExp(operandExp)})";
 | 
			
		||||
						case "System.Decimal": return $"cast({getExp(operandExp)} as decimal(36,18))";
 | 
			
		||||
						case "System.Double": return $"cast({getExp(operandExp)} as double)";
 | 
			
		||||
						case "System.Int16":
 | 
			
		||||
						case "System.Int32":
 | 
			
		||||
						case "System.Int64":
 | 
			
		||||
						case "System.SByte": return $"cast({getExp(operandExp)} as smallint)";
 | 
			
		||||
						case "System.Single": return $"cast({getExp(operandExp)} as float)";
 | 
			
		||||
						case "System.String": return $"cast({getExp(operandExp)} as character)";
 | 
			
		||||
						case "System.UInt16": return $"cast({getExp(operandExp)} as unsigned)";
 | 
			
		||||
						case "System.UInt32": return $"cast({getExp(operandExp)} as decimal(10,0))";
 | 
			
		||||
						case "System.UInt64": return $"cast({getExp(operandExp)} as decimal(21,0))";
 | 
			
		||||
						case "System.Guid": return $"substr(cast({getExp(operandExp)} as character), 1, 36)";
 | 
			
		||||
					}
 | 
			
		||||
					break;
 | 
			
		||||
				case ExpressionType.Call:
 | 
			
		||||
					var callExp = exp as MethodCallExpression;
 | 
			
		||||
 | 
			
		||||
					switch (callExp.Method.Name) {
 | 
			
		||||
						case "Parse":
 | 
			
		||||
						case "TryParse":
 | 
			
		||||
							switch (callExp.Method.DeclaringType.NullableTypeOrThis().ToString()) {
 | 
			
		||||
								case "System.Boolean": return $"({getExp(callExp.Arguments[0])} not in ('0','false'))";
 | 
			
		||||
								case "System.Byte": return $"cast({getExp(callExp.Arguments[0])} as int2)";
 | 
			
		||||
								case "System.Char": return $"substr(cast({getExp(callExp.Arguments[0])} as character), 1, 1)";
 | 
			
		||||
								case "System.DateTime": return $"datetime({getExp(callExp.Arguments[0])})";
 | 
			
		||||
								case "System.Decimal": return $"cast({getExp(callExp.Arguments[0])} as decimal(36,18))";
 | 
			
		||||
								case "System.Double": return $"cast({getExp(callExp.Arguments[0])} as double)";
 | 
			
		||||
								case "System.Int16":
 | 
			
		||||
								case "System.Int32":
 | 
			
		||||
								case "System.Int64":
 | 
			
		||||
								case "System.SByte": return $"cast({getExp(callExp.Arguments[0])} as smallint)";
 | 
			
		||||
								case "System.Single": return $"cast({getExp(callExp.Arguments[0])} as float)";
 | 
			
		||||
								case "System.UInt16": return $"cast({getExp(callExp.Arguments[0])} as unsigned)";
 | 
			
		||||
								case "System.UInt32": return $"cast({getExp(callExp.Arguments[0])} as decimal(10,0))";
 | 
			
		||||
								case "System.UInt64": return $"cast({getExp(callExp.Arguments[0])} as decimal(21,0))";
 | 
			
		||||
								case "System.Guid": return $"substr(cast({getExp(callExp.Arguments[0])} as character), 1, 36)";
 | 
			
		||||
							}
 | 
			
		||||
							break;
 | 
			
		||||
						case "NewGuid":
 | 
			
		||||
							break;
 | 
			
		||||
						case "Next":
 | 
			
		||||
							if (callExp.Object?.Type == typeof(Random)) return "cast(random()*1000000000 as int)";
 | 
			
		||||
							break;
 | 
			
		||||
						case "NextDouble":
 | 
			
		||||
							if (callExp.Object?.Type == typeof(Random)) return "random()";
 | 
			
		||||
							break;
 | 
			
		||||
						case "Random":
 | 
			
		||||
							if (callExp.Method.DeclaringType.IsNumberType()) return "random()";
 | 
			
		||||
							break;
 | 
			
		||||
						case "ToString":
 | 
			
		||||
							if (callExp.Object != null) return $"cast({getExp(callExp.Object)} as character)";
 | 
			
		||||
							break;
 | 
			
		||||
					}
 | 
			
		||||
 | 
			
		||||
					var objExp = callExp.Object;
 | 
			
		||||
					var objType = objExp?.Type;
 | 
			
		||||
					if (objType?.FullName == "System.Byte[]") return null;
 | 
			
		||||
 
 | 
			
		||||
		Reference in New Issue
	
	Block a user