|
| 1 | +--- |
| 2 | +title: Converting Filter and Sort Descriptors to SQL Queries in Blazor Grid |
| 3 | +description: Learn how to parse filter and sort descriptors from the Blazor Grid into SQL query statements for manual SQL queries execution using the OnRead event. |
| 4 | +type: how-to |
| 5 | +page_title: How to Parse Blazor Grid Descriptors into SQL Query Statements |
| 6 | +slug: grid-convert-descriptors-to-sql |
| 7 | +tags: grid, blazor, filter descriptors , sort descriptors, SQL query |
| 8 | +res_type: kb |
| 9 | +ticketid: 1666625, 1653361 |
| 10 | +--- |
| 11 | + |
| 12 | +## Environment |
| 13 | + |
| 14 | +<table> |
| 15 | + <tbody> |
| 16 | + <tr> |
| 17 | + <td>Product</td> |
| 18 | + <td>Grid for Blazor</td> |
| 19 | + </tr> |
| 20 | + </tbody> |
| 21 | +</table> |
| 22 | + |
| 23 | +## Description |
| 24 | + |
| 25 | +When using the Grid [`OnRead` event]({%slug grid-events%}#read-event) to execute SQL queries, I need to convert the Grid's filter and sort descriptors into SQL query statements. This way I can create SQL clauses for filtering and ordering items directly through SQL. |
| 26 | + |
| 27 | +This KB article also answers the following questions: |
| 28 | +- How can I convert Grid filters and sorters to SQL WHERE and ORDER BY clauses? |
| 29 | +- Is there a way to parse Grid filter and sort descriptors into SQL queries? |
| 30 | +- Can I use `DataSourceRequest`({%slug common-features-data-binding-onread%}#event-argument) to generate SQL query statements for filtering and sorting? |
| 31 | + |
| 32 | +## Solution |
| 33 | + |
| 34 | +To convert the Grid's filter and sort descriptors into SQL query statements, you need to manually construct the SQL query within the `OnRead` event handler by utilizing the `args.Request.Filters` and `args.Request.Sorts` objects. Although Telerik UI for Blazor does not provide a direct method to extract the SQL query from the `DataSourceRequest`, a manual approach can be adopted. |
| 35 | + |
| 36 | +The following steps outline how to achieve this: |
| 37 | + |
| 38 | +1. **Handle the `OnRead` Event**: Add an `OnRead` event to your Grid and in the event handler, access the `args.Request.Filters` and `args.Request.Sorts` to construct your SQL query. |
| 39 | + |
| 40 | +2. **Parse Filters**: Iterate through `args.Request.Filters` to construct the WHERE clause of your SQL query. Each filter in this collection will correspond to a column filter in the Grid. |
| 41 | + |
| 42 | +3. **Parse Sort Descriptors**: Similarly, iterate through `args.Request.Sorts` to build the ORDER BY clause of your SQL query. Each sort descriptor corresponds to a column sorting in the Grid. |
| 43 | + |
| 44 | +4. **Execute SQL Query**: With the constructed WHERE and ORDER BY clauses, form your complete SQL query and execute it against your database. |
| 45 | + |
| 46 | +5. **Set Grid Data**: Finally, assign the result of your SQL query to the Grid by setting `args.Data`. |
| 47 | + |
| 48 | +## Example |
| 49 | + |
| 50 | +Below is a simplified example demonstrating how to parse filter and sort descriptors. This example does not directly execute a SQL query but outlines how to construct the WHERE and ORDER BY clauses. |
| 51 | + |
| 52 | +```csharp |
| 53 | +@using System.Text |
| 54 | +@using Telerik.DataSource |
| 55 | +@using Telerik.DataSource.Extensions |
| 56 | + |
| 57 | +<TelerikGrid TItem="@MyItem" |
| 58 | + OnRead="@ReadItems" |
| 59 | + FilterMode="@GridFilterMode.FilterRow" |
| 60 | + Sortable="true" |
| 61 | + Pageable="true"> |
| 62 | + <GridColumns> |
| 63 | + <GridColumn Field=@nameof(MyItem.ID) /> |
| 64 | + <GridColumn Field=@nameof(MyItem.Name) /> |
| 65 | + <GridColumn Field=@nameof(MyItem.Age) /> |
| 66 | + </GridColumns> |
| 67 | +</TelerikGrid> |
| 68 | + |
| 69 | +@code { |
| 70 | + private List<MyItem> GridData { get; set; } |
| 71 | + |
| 72 | + private string SqlQuery { get; set; } |
| 73 | + private string FilterQuery { get; set; } |
| 74 | + private string SortQuery { get; set; } |
| 75 | + |
| 76 | + private async Task ReadItems(GridReadEventArgs args) |
| 77 | + { |
| 78 | + FilterQuery = BuildFilterQuery(args.Request.Filters); |
| 79 | + SortQuery = BuildSortQuery(args.Request.Sorts); |
| 80 | + |
| 81 | + if (FilterQuery != string.Empty) |
| 82 | + { |
| 83 | + SqlQuery = $"SELECT * FROM MyTable WHERE {FilterQuery}"; |
| 84 | + |
| 85 | + GridData = await ExecuteSqlQuery(SqlQuery); |
| 86 | + } |
| 87 | + else if (SortQuery != string.Empty) |
| 88 | + { |
| 89 | + SqlQuery = $"SELECT * FROM MyTable ORDER BY {SortQuery}"; |
| 90 | + |
| 91 | + GridData = await ExecuteSqlQuery(SqlQuery); |
| 92 | + } |
| 93 | + else |
| 94 | + { |
| 95 | + GridData = GenerateData(); |
| 96 | + } |
| 97 | + |
| 98 | + var datasourceResult = GridData.ToDataSourceResult(args.Request); |
| 99 | + |
| 100 | + args.Data = datasourceResult.Data; |
| 101 | + args.Total = datasourceResult.Total; |
| 102 | + } |
| 103 | + |
| 104 | + private string BuildFilterQuery(IEnumerable<IFilterDescriptor> filters) |
| 105 | + { |
| 106 | + // Implement logic to parse filters into SQL WHERE clause |
| 107 | + // Example: "Name = 'John' AND Age > 30" |
| 108 | + // You may need to adjust the SQL query depending if there are |
| 109 | + // more FilterDescriptors (when using FilterMenu filter mode) |
| 110 | + var filterQuery = new StringBuilder(); |
| 111 | + foreach (var filter in filters) |
| 112 | + { |
| 113 | + if (filter is CompositeFilterDescriptor compositeFilter) |
| 114 | + { |
| 115 | + foreach (var childFilter in compositeFilter.FilterDescriptors) |
| 116 | + { |
| 117 | + filterQuery.Append(ParseFilterDescriptor(childFilter)); |
| 118 | + } |
| 119 | + } |
| 120 | + } |
| 121 | + return filterQuery.ToString(); |
| 122 | + } |
| 123 | + |
| 124 | + private string ParseFilterDescriptor(IFilterDescriptor filter) |
| 125 | + { |
| 126 | + if (filter is FilterDescriptor descriptor) |
| 127 | + { |
| 128 | + return $"{descriptor.Member} {GetSqlOperator(descriptor.Operator)} '{descriptor.Value}'"; |
| 129 | + } |
| 130 | + return string.Empty; |
| 131 | + } |
| 132 | + |
| 133 | + private string GetSqlOperator(FilterOperator filterOperator) |
| 134 | + { |
| 135 | + return filterOperator switch |
| 136 | + { |
| 137 | + FilterOperator.IsEqualTo => "=", |
| 138 | + FilterOperator.IsNotEqualTo => "<>", |
| 139 | + FilterOperator.IsGreaterThan => ">", |
| 140 | + FilterOperator.IsGreaterThanOrEqualTo => ">=", |
| 141 | + FilterOperator.IsLessThan => "<", |
| 142 | + FilterOperator.IsLessThanOrEqualTo => "<=", |
| 143 | + FilterOperator.Contains => "LIKE", |
| 144 | + _ => throw new NotSupportedException($"Operator {filterOperator} is not supported") |
| 145 | + }; |
| 146 | + } |
| 147 | + |
| 148 | + private string BuildSortQuery(IEnumerable<SortDescriptor> sorts) |
| 149 | + { |
| 150 | + // Implement logic to parse sorters into SQL ORDER BY clause |
| 151 | + // Example: "Name ASC" |
| 152 | + return string.Join(", ", sorts.Select(s => $"{s.Member} {(s.SortDirection == ListSortDirection.Ascending ? "ASC" : "DESC")}")); |
| 153 | + } |
| 154 | + |
| 155 | + private async Task<List<MyItem>> ExecuteSqlQuery(string sqlQuery) |
| 156 | + { |
| 157 | + // Implement logic to execute the SQL query and return the result |
| 158 | + // This is a placeholder for your actual data access code |
| 159 | + if (FilterQuery != string.Empty) |
| 160 | + { |
| 161 | + } |
| 162 | + |
| 163 | + if (SortQuery != string.Empty) |
| 164 | + { |
| 165 | + } |
| 166 | + //Remove this line when you execute the SQL query |
| 167 | + //It is only for example purposes |
| 168 | + GridData = new List<MyItem>(); |
| 169 | + return GridData; |
| 170 | + } |
| 171 | + |
| 172 | + protected override void OnInitialized() |
| 173 | + { |
| 174 | + GridData = GenerateData(); |
| 175 | + } |
| 176 | + |
| 177 | + private List<MyItem> GenerateData() |
| 178 | + { |
| 179 | + var result = new List<MyItem>(); |
| 180 | + var rand = new Random(); |
| 181 | + for (int i = 0; i < 100; i++) |
| 182 | + { |
| 183 | + result.Add(new MyItem() |
| 184 | + { |
| 185 | + ID = i, |
| 186 | + Name = "Name " + i, |
| 187 | + Age = rand.Next(10, 40) |
| 188 | + }); |
| 189 | + } |
| 190 | + |
| 191 | + return result; |
| 192 | + } |
| 193 | + |
| 194 | + public class MyItem |
| 195 | + { |
| 196 | + public int ID { get; set; } |
| 197 | + public string Name { get; set; } |
| 198 | + public int Age { get; set; } |
| 199 | + } |
| 200 | +} |
| 201 | +``` |
| 202 | + |
| 203 | +## See Also |
| 204 | + |
| 205 | +- [OnRead Event Documentation]({%slug grid-events%}#read-event) |
| 206 | +- [Forum Post on Using DataSourceRequest in SQL Query](https://www.telerik.com/forums/can-datasourcerequest-be-used-in-sql-query-to-add-where-and-order-by-clauses) |
| 207 | +- [Get Information From the DataSourceRequest]({%slug components/grid/manual-operations%}#get-information-from-the-datasourcerequest) |
0 commit comments