Sphyrnidae Common Library
2.0.1
Shared Utilities/Library
|
If you don't want to fully create your own sql statement, or your sql will be somewhat dynamic in nature, this class can help. There are 2 main components to this:
If the SQL you wish to generate is known at design-time, then you should just directly generate that SQL (possibly as a Stored Procedure). However, if you are dynamically building the SQL with various tables and columns that could change, then this is the tool for now. A common scenario for this would be in report building where the user can specify which tables, columns, aggregates, ordering, etc.
You will begin by specifing the Primary Table. All you need to specify initially is the Name of the table. From there, you can utilize the DynamicSqlBuilder. The constructor will take the primary table you've created as the sole argument.
From here, you can either add columns to the table directly, or you can utilize the AddColumn() method on the DynamicSqlBuilder. You must at a minimum specify the Name. You will need to specify at least 1 column as IsSelect. On the column itself, you can also specify this column as grouping, as an aggregate (it can actually be aggregated multiple ways), or if it is involved in ordering. If you have multiple ordering columns, you should also specify the priority.
To have multiple tables in your SQL, you will create another table as a Join Table. This table is just like your primary table - so you need only specify the Name of the table. By default, this table will be joined by an inner join. You can update this join to be other types. You can then call the AddTable() method on the DynamicSqlBuilder. You can add columns the same way to this table as you did for the primary table (any calls to AddColumn() will be against the last table specified in the DynamicSqlBuilder).
In order to specify the join condition for this table, you should create a condition (see below), and then call AddCondition() method on the DynamicSqlBuilder. As with columns, the conditions will apply to the latest table specified.
A Condition can be added to the 'Where' clause to filter results. These same conditions are also used for join conditions when joining multiple tables together in your 'From' clause. To add conditions to your 'Where' clause, you should first call the BeginWhere() method on the DynamicSqlBuilder. From there, you can begin adding conditions. The first condition you add will appear immediately after the 'Where' clause. For subsequent conditions, these will be siblings of the previous condition, and you must specify how the conditions are joined together. Default join condition is And.
A condition will have the following properties:
If you are specifying a non-column, this will be of type Right Value. The value you specify will be parameterized in your SQL. Note that some Compare Operators take multiple values. For these types, you should specify the 2nd (or any subsequent) parameters in AdditionalParameterValues. Here is the listing of Compare Operators where this is required:
If you need to group conditions together - eg. to specify AND (A OR B) - you can utilize the BeginGroup() method on the DynamicSqlBuilder which will essentially write out "AND (". You can then add additional conditions to the grouping. The first condition added will not have the join condition specified. When you are done adding conditions to the group, you will call the EndGroup() method on the DynamicSqlBuilder which will essentially write out "AND (", which will essentially write out the ")". You can also nest groupings (eg. a grouping within a grouping).
This class is not meant to be all-inclusive of all possible SQL statements and structures. Only the methods documented are currently supported. If you need other functionality, a change request can be made to add that piece of functionality.
When you are done adding everything to the DynamicSqlBuilder, you will call the Build() method which will validate everything and return a DynamicSql object. If the Error property is populated, then validation failed with the specified message. Otherwise, the generated SQL and parameters will be populated.
Once you have built the sql object (see above), you now will likely want to execute that SQL. There is no need to build your own repository (see Data Access Layer), as a generic repository is available for use:
To use these classes, use dependency injection to inject the instances, and then call whatever method you would like:
The parameters to these functions are:
None
To generate the following SQL: SELECT Count([tbl1].[RoleId]) AS [NumRoles], [tbl0].[UserId] AS [UserId] FROM [Users] AS [tbl0] Left JOIN [UserRoles] AS [tbl1] ON [tbl0].[UserId] = [tbl1].[UserId] WHERE [tbl0].[UserId] <= @Param0 And ( [tbl0].[Name] = @Param1 Or [tbl0].[Name] = @Param2 ) GROUP BY [tbl0].[UserId] ORDER BY [tbl0].[Name] Asc With the following parameters: [ {"Key":"Param0","Value":100}, {"Key":"Param1","Value":"me"}, {"Key":"Param2","Value":"you"} ] You can write the following code: var usersTable = new Table { Name = "Users" }; var usersUserId = new Column { Name = "UserId", IsSelect = true, IsGrouping = true }; var usersName = new Column { Name = "Name", OrderBy = OrderDirection.Asc }; var userRolesTable = new JoinTable { Name = "UserRoles", Type = JoinType.Left }; var userRolesUserId = new Column { Name = "UserId" }; var userRolesRoleId = new Column { Name = "RoleId"}; userRolesRoleId.Aggregates.Add( new AggregateSpecification { Aggregate = Aggregate.Count, Alias = "NumRoles" }); var sqlBuilder = new DynamicSqlBuilder(usersTable); sqlBuilder.AddColumn(usersUserId); sqlBuilder.AddColumn(usersName); sqlBuilder.AddTable(userRolesTable); sqlBuilder.AddColumn(userRolesUserId); sqlBuilder.AddColumn(userRolesRoleId); sqlBuilder.AddCondition(new Condition { LeftColumn = usersUserId, Operator = CompareOperator.Equals, RightColumn = userRolesUserId }); sqlBuilder.BeginWhere(); sqlBuilder.AddCondition(new Condition { LeftColumn = usersUserId, Operator = CompareOperator.LessThanOrEqual, RightValue = 100 }); sqlBuilder.BeginGroup(ConditionJoin.And); sqlBuilder.AddCondition(new Condition { LeftColumn = usersName, Operator = CompareOperator.Equals, RightValue = "me" }); sqlBuilder.AddCondition(new Condition { Join = ConditionJoin.Or, LeftColumn = usersName, Operator = CompareOperator.Equals, RightValue = "you" }); sqlBuilder.EndGroup(); var sql = sqlBuilder.Build(SqlType.SqlServer);