diff --git a/README.md b/README.md index 28b7adb..c247c5c 100644 --- a/README.md +++ b/README.md @@ -184,7 +184,7 @@ builder - Consider query performance when building complex JOINs ## Limitations -1. Limited support for complex subqueries +1. Limited support for complex subqueries (could use RawSql methods for this) 2. No direct support for GROUP BY and HAVING clauses 3. No NamingConvention support for table and column (e.g. SnakeCase, PascalCase for table and column names) @@ -195,6 +195,10 @@ builder - .NET 7.0+ ## Version History +- 1.1.0 + - Add RawSql methods (Where, And, Or, OrderBy) and AppendRawSql method + - Change parameter type from LambdaExpression to Expression> for strongly-typed expressions + - 1.0.0 - Initial release - Basic SQL query building diff --git a/src/SqlBuilder/SqlBuilder.cs b/src/SqlBuilder/SqlBuilder.cs index ba8dccf..fe6501c 100644 --- a/src/SqlBuilder/SqlBuilder.cs +++ b/src/SqlBuilder/SqlBuilder.cs @@ -146,56 +146,45 @@ private string GetTablePrefix(Type type, bool alwaysCreateNew) tableAliasIndex++; return newPrefix; } - + /// - /// Adds a SELECT * clause for a type, with options to exclude specific columns. + /// Adds a SELECT * clause for a type, with options to exclude specific columns and specify a first column. /// /// The entity type /// Columns to exclude from the selection /// Column to place first in the selection - /// Output parameter for the generated table prefix + /// Optional table prefix/alias /// The current SqlBuilder instance for method chaining - public SqlBuilder SelectAll(LambdaExpression[]? excludeColumns, LambdaExpression? firstColumn, out string prefix) + public SqlBuilder SelectAll(Expression>[]? excludeColumns, Expression>? firstColumn, string? prefix = null) { - prefix = GetTablePrefix(typeof(T), true); + prefix ??= GetTablePrefix(typeof(T), false); AppendSelect(Utils.GenerateSelectAllColumns(typeof(T), isSqlServer, excludeColumns, firstColumn, prefix)); return this; } /// - /// Adds a SELECT * clause for a type, excluding specific columns. + /// Adds a SELECT * clause for a type, with options to exclude specific columns. /// /// The entity type /// Columns to exclude from the selection + /// Column to place first in the selection /// Output parameter for the generated table prefix /// The current SqlBuilder instance for method chaining - public SqlBuilder SelectAll(LambdaExpression[]? excludeColumns, out string prefix) + public SqlBuilder SelectAll(Expression>[]? excludeColumns, Expression>? firstColumn, out string prefix) { - return SelectAll(excludeColumns, null, out prefix); - } - - /// - /// Adds a SELECT * clause for a type, with options to exclude specific columns and specify a first column. - /// - /// - /// - /// - /// - /// - public SqlBuilder SelectAll(Expression>[]? excludeColumns, Expression>? firstColumn, string? prefix = null) - { - prefix ??= GetTablePrefix(typeof(T), false); + prefix = GetTablePrefix(typeof(T), true); AppendSelect(Utils.GenerateSelectAllColumns(typeof(T), isSqlServer, excludeColumns, firstColumn, prefix)); return this; } + /// /// Adds a SELECT * clause for a type, excluding specific columns. /// - /// - /// - /// - /// + /// The entity type + /// Columns to exclude from the selection + /// Optional table prefix/alias + /// The current SqlBuilder instance for method chaining public SqlBuilder SelectAll(Expression>[]? excludeColumns, string? prefix = null) { return SelectAll(excludeColumns, null, prefix); @@ -204,9 +193,9 @@ public SqlBuilder SelectAll(Expression>[]? excludeColumns, st /// /// Adds a SELECT * clause for a type, with options to specify a first column. /// - /// - /// - /// + /// The entity type + /// Column to place first in the selection + /// Optional table prefix/alias /// The current SqlBuilder instance for method chaining public SqlBuilder SelectAll(Expression>? firstColumn, out string prefix) { @@ -360,14 +349,16 @@ public SqlBuilder From(string? prefix = null) } /// - /// Adds a WHERE clause to the query. + /// Adds a WHERE clause to the query. /// + /// The entity type + /// The column type /// The column expression /// The value to compare against /// The comparison operator (defaults to "=") /// Optional table prefix/alias /// The current SqlBuilder instance for method chaining - public SqlBuilder Where(LambdaExpression expression, string value, string op = "=", string? prefix = null) + public SqlBuilder Where(Expression> expression, string value, string op = "=", string? prefix = null) { sqlBuilder.Append(" WHERE "); sqlBuilder.Append(Utils.EncodeColumn(Utils.GetColumnName(expression), isSqlServer, prefix, null, false)); @@ -376,20 +367,27 @@ public SqlBuilder Where(LambdaExpression expression, string value, string op = " } /// - public SqlBuilder Where(Expression> expression, string value, string op = "=", string? prefix = null) + /// Adds a WHERE clause to the query. + /// + /// The raw SQL string + /// The current SqlBuilder instance for method chaining + public SqlBuilder Where(string rawSql) { - return Where((LambdaExpression)expression, value, op, prefix); + sqlBuilder.Append(" WHERE ").Append(rawSql).AppendLine(); + return this; } /// /// Adds an AND condition to the WHERE clause. /// + /// The entity type + /// The column type /// The column expression /// The value to compare against /// The comparison operator (defaults to "=") /// Optional table prefix/alias /// The current SqlBuilder instance for method chaining - public SqlBuilder And(LambdaExpression expression, string value, string op = "=", string? prefix = null) + public SqlBuilder And(Expression> expression, string value, string op = "=", string? prefix = null) { sqlBuilder.Append(" AND "); sqlBuilder.Append(Utils.EncodeColumn(Utils.GetColumnName(expression), isSqlServer, prefix, null, false)); @@ -397,24 +395,14 @@ public SqlBuilder And(LambdaExpression expression, string value, string op = "=" return this; } - public SqlBuilder And(Expression> expression, string value, string op = "=", string? prefix = null) - { - return And((LambdaExpression)expression, value, op, prefix); - } - /// - /// Adds an OR condition to the WHERE clause. + /// Adds an AND condition to the WHERE clause. /// - /// The column expression - /// The value to compare against - /// The comparison operator (defaults to "=") - /// Optional table prefix/alias + /// The raw SQL string /// The current SqlBuilder instance for method chaining - public SqlBuilder Or(LambdaExpression expression, string value, string op = "=", string? prefix = null) + public SqlBuilder And(string rawSql) { - sqlBuilder.Append(" OR "); - sqlBuilder.Append(Utils.EncodeColumn(Utils.GetColumnName(expression), isSqlServer, prefix, null, false)); - sqlBuilder.Append(" ").Append(op).Append(" ").Append(value).AppendLine(); + sqlBuilder.Append(" AND ").Append(rawSql).AppendLine(); return this; } @@ -430,24 +418,24 @@ public SqlBuilder Or(LambdaExpression expression, string value, string op = "=", /// public SqlBuilder Or(Expression> expression, string value, string op = "=", string? prefix = null) { - return Or((LambdaExpression)expression, value, op, prefix); + sqlBuilder.Append(" OR "); + sqlBuilder.Append(Utils.EncodeColumn(Utils.GetColumnName(expression), isSqlServer, prefix, null, false)); + sqlBuilder.Append(" ").Append(op).Append(" ").Append(value).AppendLine(); + return this; } /// - /// Adds an ORDER BY clause to the query. + /// Adds an OR condition to the WHERE clause. /// - /// The column expression to order by - /// Whether to order ascending (true) or descending (false) - /// Optional table prefix/alias + /// The raw SQL string /// The current SqlBuilder instance for method chaining - public SqlBuilder OrderBy(LambdaExpression expression, bool ascOrder = true, string? prefix = null) + public SqlBuilder Or(string rawSql) { - sqlBuilder.Append(" ORDER BY "); - sqlBuilder.Append(Utils.EncodeColumn(Utils.GetColumnName(expression), isSqlServer, prefix, null, false)); - sqlBuilder.Append(" ").Append(ascOrder ? "ASC" : "DESC").AppendLine(); + sqlBuilder.Append(" OR ").Append(rawSql).AppendLine(); return this; } + /// /// Adds an ORDER BY clause to the query. /// @@ -459,7 +447,21 @@ public SqlBuilder OrderBy(LambdaExpression expression, bool ascOrder = true, str /// public SqlBuilder OrderBy(Expression> expression, bool ascOrder = true, string? prefix = null) { - return OrderBy((LambdaExpression)expression, ascOrder, prefix); + sqlBuilder.Append(" ORDER BY "); + sqlBuilder.Append(Utils.EncodeColumn(Utils.GetColumnName(expression), isSqlServer, prefix, null, false)); + sqlBuilder.Append(" ").Append(ascOrder ? "ASC" : "DESC").AppendLine(); + return this; + } + + /// + /// Adds an ORDER BY clause to the query. + /// + /// The raw SQL string + /// The current SqlBuilder instance for method chaining + public SqlBuilder OrderBy(string rawSql, bool ascOrder = true) + { + sqlBuilder.Append(" ORDER BY ").Append(rawSql).Append(" ").Append(ascOrder ? "ASC" : "DESC").AppendLine(); + return this; } /// @@ -541,6 +543,17 @@ public SqlBuilder FullJoin(Expression return BuildJoinClause(left, right, leftPrefix, rightPrefix, op); } + /// + /// Appends raw SQL to the query. + /// + /// The raw SQL string + /// The current SqlBuilder instance for method chaining + public SqlBuilder AppendRawSql(string rawSql) + { + sqlBuilder.Append(rawSql); + return this; + } + /// /// Builds and returns the complete SQL query string. /// diff --git a/src/SqlBuilder/SqlBuilder.csproj b/src/SqlBuilder/SqlBuilder.csproj index 8d0e4d6..abbbfbc 100644 --- a/src/SqlBuilder/SqlBuilder.csproj +++ b/src/SqlBuilder/SqlBuilder.csproj @@ -16,7 +16,7 @@ https://github.com/guanghuang/SqlBuilder Query;Sql;SqlBuilder enable - 1.0.0 + 1.1.0 Copyright © 2024 Kvr.SqlBuilder. All rights reserved.