/// <summary> /// 根据传入的值,创建一个 NpgsqlParameter 对象,并装入属性 Parameters 中 /// </summary> /// <param name="val">参数的值</param> /// <param name="type">运算符类型</param> /// <param name="specificType">数据库指定列的类型</param> protected void SetValue(object val, ExpressionType type, Type specificType = null) { if (val == null) { CommandText.Remove(CommandText.Length - 3, 3); if (type == ExpressionType.Equal) { CommandText.Append(" IS NULL"); } else if (type == ExpressionType.NotEqual) { CommandText.Append(" IS NOT NULL"); } } else { string p_key = Guid.NewGuid().ToString("N"); NpgsqlParameter parameter = null; if (specificType != null) { parameter = new NpgsqlParameter(p_key, NpgsqlDbType.Enum); parameter.SpecificType = specificType; parameter.Value = val; } else { parameter = new NpgsqlParameter(p_key, val); } Parameters.Add(parameter); CommandText.Append($"@{p_key}"); } }
/// <summary> /// 根据传入的值,创建一个 NpgsqlParameter 对象,并装入属性 Parameters 中 /// </summary> /// <param name="val">参数的值</param> /// <param name="type">运算符类型</param> /// <param name="specificType">数据库指定列的类型</param> protected void SetValue(object val, ExpressionType type) { if (val == null) { CommandText.Remove(CommandText.Length - 3, 3); if (type == ExpressionType.Equal) { CommandText.Append(" IS NULL"); } else if (type == ExpressionType.NotEqual) { CommandText.Append(" IS NOT NULL"); } } else { string p_key = Guid.NewGuid().ToString("N"); NpgsqlParameter parameter = new NpgsqlParameter(p_key, val); Parameters.Add(parameter); CommandText.Append($"@{p_key}"); } }
/// <summary> /// 表达式解析主入口方法,方法重载 /// </summary> /// <param name="selector">待解析的表达式</param> /// <param name="parent_type">父级表达式节点类型</param> private void ExpressionCapture(Expression selector, ExpressionType parent_type) { if (selector is BinaryExpression be) { ExpressionProvider(be.Left, be.Right, be.NodeType); } else if (selector is MemberExpression me) { if (!selector.ToString().StartsWith("value(") && selector.Type != typeof(DateTime) || ( me.Expression != null && me.Expression.NodeType == ExpressionType.Parameter && !me.ToString().StartsWith("value(") && me.Type == typeof(DateTime) )) { string tableName = me.Member.DeclaringType == MasterType ? Master_AlisName : Union_AlisName; if (!string.IsNullOrEmpty(tableName)) { tableName = tableName + "."; } CommandText.Append($"{tableName}{me.Member.Name}"); } else { InvokeExpression(selector, parent_type); } } else if (selector is NewArrayExpression ae) { foreach (Expression ex in ae.Expressions) { ExpressionCapture(ex, parent_type); CommandText.Append(","); } CommandText.Remove(CommandText.Length - 1, 1); } else if (selector is MethodCallExpression callExp) { CommandText.Append("("); switch (callExp.Method.Name) { case "Like": ExpressionCapture(callExp.Arguments[0], parent_type); CommandText.Append($" ILIKE '%' || "); ExpressionCapture(callExp.Arguments[1], parent_type); CommandText.Append(" || '%'"); break; case "NotLike": ExpressionCapture(callExp.Arguments[0], parent_type); CommandText.Append($" NOT ILIKE '%' || "); ExpressionCapture(callExp.Arguments[1], parent_type); CommandText.Append(" || '%'"); break; case "In": ExpressionCapture(callExp.Arguments[0], parent_type); In_Not_Parameter(callExp.Arguments[1], "IN"); break; case "NotIn": ExpressionCapture(callExp.Arguments[0], parent_type); In_Not_Parameter(callExp.Arguments[1], "NOT IN"); break; default: try { InvokeExpression(selector, parent_type); } catch (Exception ex) { throw new NotSupportedException("使用数据库字段和CLR对象进行函数计算查询时,仅支持 Like,NotLike,In,NotIn 查询", ex); } break; } CommandText.Append(")"); } else if (selector is ConstantExpression ce) { if (this.Left is UnaryExpression) { Type type = ((UnaryExpression)this.Left).Operand.Type; if (type.BaseType.Name == "Enum") { object val = Enum.Parse(type, ce.Value.ToString()); SetValue(val, parent_type, type); } else { SetValue(ce.Value, parent_type); } } else { SetValue(ce.Value, parent_type); } } else if (selector is UnaryExpression ue) { ExpressionCapture(ue.Operand, parent_type); } else if (selector is ParameterExpression) { InvokeExpression(selector, parent_type); } else if (selector is NewExpression) { InvokeExpression(selector, parent_type); } }