From fde4df88f6b470890ee95ce90e095ce491834611 Mon Sep 17 00:00:00 2001 From: Naveen Date: Thu, 7 Mar 2024 10:52:33 +0530 Subject: [PATCH 1/5] MYSQL-Data-Binding-Documentation(871699) --- blazor-toc.html | 1 + .../connecting-to-database/mysql-server.md | 1232 +++++++++++++++++ 2 files changed, 1233 insertions(+) create mode 100644 blazor/datagrid/connecting-to-database/mysql-server.md diff --git a/blazor-toc.html b/blazor-toc.html index 2f479fe230..3d97a022d7 100644 --- a/blazor-toc.html +++ b/blazor-toc.html @@ -1569,6 +1569,7 @@
  • Connecting to Database
  • diff --git a/blazor/datagrid/connecting-to-database/mysql-server.md b/blazor/datagrid/connecting-to-database/mysql-server.md new file mode 100644 index 0000000000..b2541e46a7 --- /dev/null +++ b/blazor/datagrid/connecting-to-database/mysql-server.md @@ -0,0 +1,1232 @@ +--- +layout: post +title: MySQL Data Binding in Blazor DataGrid Component | Syncfusion +description: Learn about consuming data from MYSQL Server and binding it to Syncfusion Component, and performing CRUD operations. +platform: Blazor +control: DataGrid +documentation: ug +--- + +# Connecting MySQL Server data in to Blazor DataGrid Component + +This section describes how to connect and retrieve data from a MySQL Server database using [MySQL data](https://www.nuget.org/packages/MySql.Data) and bind it to the Blazor DataGrid component. + +MySQL Server database can be bound to the Blazor DataGrid component in different ways (i.e.) using [DataSource](https://help.syncfusion.com/cr/blazor/Syncfusion.Blazor.Grids.SfGrid-1.html#Syncfusion_Blazor_Grids_SfGrid_1_DataSource) property, [CustomAdaptor](https://blazor.syncfusion.com/documentation/datagrid/custom-binding) feature and remote data binding using various adaptors. In this documentation, two approaches will be examined to connect a MySQL Server database to a Blazor DataGrid component. Both the approaches have capability to handle data and CRUD operations with built-in methods as well as can be customized as per your own. + +* **Using UrlAdaptor** + +The [UrlAdaptor](https://blazor.syncfusion.com/documentation/data/adaptors#url-adaptor) serves as the base adaptor for facilitating communication between remote data services and an UI component. It enables the remote binding of data to the Blazor DataGrid component by connecting to an existing pre-configured API service linked to the MySQL Server database. While the Blazor DataGrid component supports various adaptors to fulfill this requirement, including [Web API](https://blazor.syncfusion.com/documentation/data/adaptors#web-api-adaptor), [OData](https://blazor.syncfusion.com/documentation/data/adaptors#odata-adaptor), [ODataV4](https://blazor.syncfusion.com/documentation/data/adaptors#odatav4-adaptor), [Url](https://blazor.syncfusion.com/documentation/data/adaptors#url-adaptor), and [GraphQL](https://blazor.syncfusion.com/documentation/data/adaptors#graphql-service-binding), the `UrlAdaptor` is particularly useful for the scenarios where a custom API service with unique logic for handling data and CRUD operations is in place. This approach allows for custom handling of data and CRUD operations, and the resultant data returned in the `Result` and `Count` format for display in the Blazor DataGrid component. + +* **Using CustomAdaptor** + +The [CustomAdaptor](https://blazor.syncfusion.com/documentation/datagrid/custom-binding) serves as a mediator between the UI component and the database for data binding. While the data source from the database can be directly bound to the `SfGrid` component locally using the [DataSource](https://help.syncfusion.com/cr/blazor/Syncfusion.Blazor.Grids.SfGrid-1.html#Syncfusion_Blazor_Grids_SfGrid_1_DataSource) property, the `CustomAdaptor` approach is preferred as it allows for customization of both data operations and CRUD operations according to specific requirements. In this approach, for every action in the Blazor DataGrid component, a corresponding request with action details is sent to the `CustomAdaptor`. The Blazor DataGrid component provides predefined methods to perform data operations such as **searching**, **filtering**, **sorting**, **aggregation**, **paging** and **grouping**. Alternatively, your own custom methods can be employed to execute operations and return the data in the `Result` and `Count` format of the `DataResult` class for displaying in the Blazor DataGrid component. Additionally, for CRUD operations, predefined methods can be overridden to provide custom functionality. Further details on this can be found in the latter part of the documentation. + +## Binding data from MySQL Server using an API service + +This section describes step by step process how to retrieve data from a MySQL server using an API service and bind it to the Blazor DataGrid component. + +### Creating an API service + +**1.** Open Visual Studio and create an ASP.NET Core Web App project type, naming it **MyWebService**. To create an ASP.NET Core Web application, follow the documentation [link](https://learn.microsoft.com/en-us/visualstudio/get-started/csharp/tutorial-aspnet-core?view=vs-2022). + +**2.** To connect a MySQL Server database using the MySQL driver in your application, you need to install the [MySQL.Data](https://www.nuget.org/packages/MySql.Data) NuGet package. To add **MySQL.Data** in the app, open the NuGet package manager in Visual Studio (Tools → NuGet Package Manager → Manage NuGet Packages for Solution), search and install it. + +**3.** Create an API controller (aka, GridController.cs) file under **Controllers** folder that helps to establish data communication with the Blazor DataGrid component. + +**4.** In an API controller (aka, GridController), connect to MySQL Server. In the **Get()** method **MySqlConnection** helps to connect the MySQL Server database. Next, using **MySqlCommand** and **MySqlDataAdapter** you can process the desired SQL query string and retrieve data from the database. The **Fill** method of the **DataAdapter** is used to populate the SQL data into a **DataTable** as shown in the following code snippet. + +{% tabs %} +{% highlight razor tabtitle="GridController.cs"%} +using Microsoft.AspNetCore.Mvc; +using MySql.Data.MySqlClient; +using System.Data; +using Syncfusion.Blazor; +using Syncfusion.Blazor.Data; +using System.ComponentModel.DataAnnotations; +using Newtonsoft.Json; + +namespace MySqlWebService.Controllers +{ + [ApiController] + public class GridController : ControllerBase + { + public static List Orders { get; set; } + + public class Order + { + [Key] + public int? OrderID { get; set; } + public string? CustomerName { get; set; } + public int? EmployeeID { get; set; } + public decimal? Freight { get; set; } + public string? ShipCity { get; set; } + } + + [Route("api/[controller]")] + public List GetOrderData() + { + //TODO: Enter the connectionstring of database + string ConnectionString = @""; + string QueryStr = "SELECT * FROM orders ORDER BY OrderID"; + MySqlConnection sqlConnection = new(ConnectionString); + sqlConnection.Open(); + //Execute the MySQL Command + MySqlCommand SqlCommand = new(QueryStr, sqlConnection); + //Using MySqlDataAdapter and Query create connection with database + MySqlDataAdapter DataAdapter = new(SqlCommand); + DataTable DataTable = new(); + // Using MySqlDataAdapter, process the query string and fill the data into the dataset + DataAdapter.Fill(DataTable); + sqlConnection.Close(); + //Cast the data fetched from Adaptor to List + var DataSource = (from DataRow Data in DataTable.Rows + select new Order() + { + OrderID = Convert.ToInt32(Data["OrderID"]), + CustomerName = Data["CustomerName"].ToString(), + EmployeeID = Convert.ToInt32(Data["EmployeeID"]), + ShipCity = Data["ShipCity"].ToString(), + Freight = Convert.ToDecimal(Data["Freight"]) + }).ToList(); + return DataSource; + } + } +} +{% endhighlight %} +{% endtabs %} + +**5.** Run the application and it will be hosted within the URL `https://localhost:xxxx`. + +**6.** Finally, the retrieved data from MySQL Server database which is in the form of list of array can be found in an API controller available in the URL link `https://localhost:xxxx/api/Grid`, as shown in the browser page below. + +![Hosted API URL](../images/Ms-Sql-data.png) + +### Connecting Blazor DataGrid to an API service + +**1.** Create a simple Blazor DataGrid component by following steps. This section briefly explains about how to include [Blazor DataGrid](https://www.syncfusion.com/blazor-components/blazor-datagrid) component in your Blazor Web App using [Visual Studio](https://visualstudio.microsoft.com/vs/). + +**Prerequisites** + +* [System requirements for Blazor components](https://blazor.syncfusion.com/documentation/system-requirements) + +**Create a new Blazor Web App** + +You can create a **Blazor Web App** using Visual Studio 2022 via [Microsoft Templates](https://learn.microsoft.com/en-us/aspnet/core/blazor/tooling?view=aspnetcore-8.0) or the [Syncfusion Blazor Extension](https://blazor.syncfusion.com/documentation/visual-studio-integration/template-studio). + +You need to configure the corresponding [Interactive render mode](https://learn.microsoft.com/en-us/aspnet/core/blazor/components/render-modes?view=aspnetcore-8.0#render-modes) and [Interactivity location](https://learn.microsoft.com/en-us/aspnet/core/blazor/tooling?view=aspnetcore-8.0&pivots=windows) while creating a Blazor Web Application. + +**Install Syncfusion Blazor Grid and Themes NuGet in the Blazor Web App** + +To add **Blazor DataGrid** component in the app, open the NuGet package manager in Visual Studio (*Tools → NuGet Package Manager → Manage NuGet Packages for Solution*), search and install [Syncfusion.Blazor.Grid](https://www.nuget.org/packages/Syncfusion.Blazor.Grid/) and [Syncfusion.Blazor.Themes](https://www.nuget.org/packages/Syncfusion.Blazor.Themes/). + +If you utilize `WebAssembly or Auto` render modes in the Blazor Web App need to be install Syncfusion Blazor components NuGet packages within the client project. + +Alternatively, you can utilize the following package manager command to achieve the same. + +{% tabs %} +{% highlight C# tabtitle="Package Manager" %} + +Install-Package Syncfusion.Blazor.Grid -Version {{ site.releaseversion }} +Install-Package Syncfusion.Blazor.Themes -Version {{ site.releaseversion }} + +{% endhighlight %} +{% endtabs %} + +> Syncfusion Blazor components are available in [nuget.org](https://www.nuget.org/packages?q=syncfusion.blazor). Refer to [NuGet packages](https://blazor.syncfusion.com/documentation/nuget-packages) topic for available NuGet packages list with component details. + +**Register Syncfusion Blazor Service** + +Open **~/_Imports.razor** file and import the `Syncfusion.Blazor` and `Syncfusion.Blazor.Grids` namespace. + +```cshtml + +@using Syncfusion.Blazor +@using Syncfusion.Blazor.Grids +``` + +Now, register the Syncfusion Blazor Service in the **~/Program.cs** file of your Blazor Web App. For a app with `WebAssembly` or `Auto (Server and WebAssembly)` interactive render mode, register the Syncfusion Blazor service in both **~/Program.cs** files of your web app. + +```cshtml + +.... +using Syncfusion.Blazor; +.... +builder.Services.AddSyncfusionBlazor(); +.... + +``` + +**Add stylesheet and script resources** + +The theme stylesheet and script can be accessed from NuGet through [Static Web Assets](https://blazor.syncfusion.com/documentation/appearance/themes#static-web-assets). Include the stylesheet reference in the `` section and the script reference at the end of the `` in the **~/Components/App.razor** file as shown below: + +```html + + .... + + +.... + + .... + + +``` + +> * Check out the [Blazor Themes](https://blazor.syncfusion.com/documentation/appearance/themes) topic to discover various methods ([Static Web Assets](https://blazor.syncfusion.com/documentation/appearance/themes#static-web-assets), [CDN](https://blazor.syncfusion.com/documentation/appearance/themes#cdn-reference), and [CRG](https://blazor.syncfusion.com/documentation/common/custom-resource-generator)) for referencing themes in your Blazor application. Also, check out the [Adding Script Reference](https://blazor.syncfusion.com/documentation/common/adding-script-references) topic to learn different approaches for adding script references in your Blazor application. +> * In this Blazor Web app, set the `rendermode` as either **InteractiveServer** or **InteractiveAuto** as per your configuration. + +**2.** Map the hosted API's URL link `https://localhost:xxxx/api/Grid` to the Blazor DataGrid component in **Index.razor** by using the [Url](https://help.syncfusion.com/cr/blazor/Syncfusion.Blazor.DataManager.html#Syncfusion_Blazor_DataManager_Url) property of [SfDataManager](https://help.syncfusion.com/cr/blazor/Syncfusion.Blazor.Data.SfDataManager.html). To interact with remote data source, provide the endpoint `Url`. + +**3.** The `SfDataManager` offers multiple adaptor options to connect with remote database based on an API service. Below is an example of the [UrlAdaptor](https://blazor.syncfusion.com/documentation/data/adaptors#url-adaptor) configuration where an API service are set up to return the resulting data in the `Result` and `Count` format. + +**4.** The `UrlAdaptor` acts as the base adaptor for interacting with remote data service. Most of the built-in adaptors are derived from the `UrlAdaptor`. + +{% tabs %} +{% highlight razor tabtitle="Index.razor"%} +@using Syncfusion.Blazor.Grids +@using Syncfusion.Blazor.Data +@using Syncfusion.Blazor + + + + + + + + + + @{ + var aggregate = (context as AggregateTemplateContext); +
    +

    Sum: @aggregate.Sum

    +
    + } +
    +
    +
    +
    + + + + + @{ + var aggregate = (context as AggregateTemplateContext); +
    +

    Average: @aggregate.Average

    +
    + } +
    +
    +
    +
    +
    + + + + + + + +
    + +@code { + SfGrid Grid { get; set; } + public List Orders { get; set; } + public class Order + { + public int? OrderID { get; set; } + public string CustomerName { get; set; } + public int EmployeeID { get; set; } + public decimal Freight { get; set; } + public string ShipCity { get; set; } + } +} +{% endhighlight %} +{% highlight c# tabtitle="GridController.cs"%} +[ApiController] +public class GridController : ControllerBase +{ + /// + /// Returns the data collection as result and count after performing data operations based on request from + /// + /// DataManagerRequest contains the information regarding searching, filtering, sorting, aggregates and paging which is handled on the DataGrid component side + /// The data collection's type is determined by how this method has been implemented. + [HttpPost] + [Route("api/[controller]")] + public object Post([FromBody] DataManagerRequest DataManagerRequest) + { + IEnumerable DataSource = GetOrderData(); + // Handling Searching in Url Adaptor. + if (DataManagerRequest.Search != null && DataManagerRequest.Search.Count > 0) + { + // Searching + DataSource = DataOperations.PerformSearching(DataSource, DataManagerRequest.Search); + } + // Handling Filtering in Url Adaptor. + if (DataManagerRequest.Where != null && DataManagerRequest.Where.Count > 0) + { + // Filtering + DataSource = DataOperations.PerformFiltering(DataSource, DataManagerRequest.Where, DataManagerRequest.Where[0].Operator); + } + // Handling Sorting in Url Adaptor. + if (DataManagerRequest.Sorted != null && DataManagerRequest.Sorted.Count > 0) + { + // Sorting + DataSource = DataOperations.PerformSorting(DataSource, DataManagerRequest.Sorted); + } + int count = DataSource.Cast().Count(); + // Handling Aggregation in Url Adaptor. + IDictionary Aggregates = null; + if (DataManagerRequest.Aggregates != null) // Aggregation + { + Aggregates = DataUtil.PerformAggregation(DataSource, DataManagerRequest.Aggregates); + } + // Handling paging in Url Adaptor. + if (DataManagerRequest.Skip != 0) + { + // Paging + DataSource = DataOperations.PerformSkip(DataSource, DataManagerRequest.Skip); + } + if (DataManagerRequest.Take != 0) + { + DataSource = DataOperations.PerformTake(DataSource, DataManagerRequest.Take); + } + //Here RequiresCount is passed from the control side itself, where ever the ondemand data fetching is needed then the RequiresCount is set as true in component side itself. + // In the above case we are using Paging so data are loaded in ondemand bases whenever the next page is clicked in DataGrid side. + return new { result = DataSource, count = count, aggregates = Aggregates }; + } +} +{% endhighlight %} +{% endtabs %} + +> In the above Blazor DataGrid component, [AllowSearching](https://help.syncfusion.com/cr/blazor/Syncfusion.Blazor.Grids.GridColumn.html#Syncfusion_Blazor_Grids_GridColumn_AllowSearching), [AllowSorting](https://help.syncfusion.com/cr/blazor/Syncfusion.Blazor.Grids.SfGrid-1.html#Syncfusion_Blazor_Grids_SfGrid_1_AllowSorting), [AllowFiltering](https://help.syncfusion.com/cr/blazor/Syncfusion.Blazor.Grids.SfGrid-1.html#Syncfusion_Blazor_Grids_SfGrid_1_AllowFiltering), [AllowPaging](https://help.syncfusion.com/cr/blazor/Syncfusion.Blazor.Grids.SfGrid-1.html#Syncfusion_Blazor_Grids_SfGrid_1_AllowPaging), [AllowGrouping](https://help.syncfusion.com/cr/blazor/Syncfusion.Blazor.Grids.SfGrid-1.html#Syncfusion_Blazor_Grids_SfGrid_1_AllowGrouping) and CRUD-related properties have been enabled. The details on how to handle these actions are explained below. + +When you run the application, the resultant Blazor DataGrid component will look like this + +![Blazor DataGrid component bound with MySQL Server data](../images/blazor-Grid-Ms-SQL-databinding.png) + +> * The Syncfusion Blazor DataGrid component provides built-in support for handling various data operations such as **searching**, **sorting**, **filtering**, **aggregate**, **paging** and **grouping** on the server-side. These operations can be handled using methods such as `PerformSearching`, `PerformFiltering`, `PerformSorting`, `PerformAggregation`, `PerformTake` and `PerformSkip` available in the **Syncfusion.Blazor.Data** package. Let's explore how to manage these data operations using the `UrlAdaptor`. +> * In an API service project, add **Syncfusion.Blazor.Data** by opening the NuGet package manager in Visual Studio (Tools → NuGet Package Manager → Manage NuGet Packages for Solution), search and install it. + +### Handling searching operation + +To handle searching operation, ensure that your API endpoint supports custom searching criteria. Implement the searching logic on the server-side using the [PerformSearching](https://help.syncfusion.com/cr/blazor/Syncfusion.Blazor.DataOperations.html#Syncfusion_Blazor_DataOperations_PerformSearching__1_System_Collections_Generic_IEnumerable___0__System_Collections_Generic_List_Syncfusion_Blazor_Data_SearchFilter__) method from the [DataOperations](https://help.syncfusion.com/cr/blazor/Syncfusion.Blazor.DataOperations.html) class. This allows the custom data source to undergo searching based on the criteria specified in the incoming [DataManagerRequest](https://help.syncfusion.com/cr/blazor/Syncfusion.Blazor.DataManagerRequest.html) object. + +{% highlight razor %} + +[HttpPost] +[Route("api/[controller]")] +public object Post([FromBody] DataManagerRequest DataManagerRequest) +{ + IEnumerable DataSource = GetOrderData(); + // Handling Searching in Url Adaptor. + if (DataManagerRequest.Search != null && DataManagerRequest.Search.Count > 0) + { + // Searching + DataSource = DataOperations.PerformSearching(DataSource, DataManagerRequest.Search); + //Add custom logic here if needed and remove above method + } + int count = DataSource.Cast().Count(); + return new { result = DataSource, count = count }; +} +{% endhighlight %} + +### Handling filtering operation + +To handle filtering operation, ensure that your API endpoint supports custom filtering criteria. Implement the filtering logic on the server-side using the [PerformFiltering](https://help.syncfusion.com/cr/blazor/Syncfusion.Blazor.DataOperations.html#Syncfusion_Blazor_DataOperations_PerformFiltering_System_Collections_IEnumerable_System_Collections_Generic_List_Syncfusion_Blazor_Data_WhereFilter__System_String_) method from the [DataOperations](https://help.syncfusion.com/cr/blazor/Syncfusion.Blazor.DataOperations.html) class. This allows the custom data source to undergo filtering based on the criteria specified in the incoming [DataManagerRequest](https://help.syncfusion.com/cr/blazor/Syncfusion.Blazor.DataManagerRequest.html) object. + +{% highlight razor %} +[HttpPost] +[Route("api/[controller]")] +public object Post([FromBody] DataManagerRequest DataManagerRequest) +{ + IEnumerable DataSource = GetOrderData(); + // Handling Filtering in Url Adaptor. + if (DataManagerRequest.Where != null && DataManagerRequest.Where.Count > 0) + { + // Filtering + DataSource = DataOperations.PerformFiltering(DataSource, DataManagerRequest.Where, DataManagerRequest.Where[0].Operator); + //Add custom logic here if needed and remove above method + } + int count = DataSource.Cast().Count(); + return new { result = DataSource, count = count }; +} + +{% endhighlight %} + +### Handling sorting operation + +To handle sorting operation, ensure that your API endpoint supports custom sorting criteria. Implement the sorting logic on the server-side using the [PerformSorting](https://help.syncfusion.com/cr/blazor/Syncfusion.Blazor.DataOperations.html#Syncfusion_Blazor_DataOperations_PerformSorting__1_System_Collections_Generic_IEnumerable___0__System_Collections_Generic_List_Syncfusion_Blazor_Data_Sort__) method from the [DataOperations](https://help.syncfusion.com/cr/blazor/Syncfusion.Blazor.DataOperations.html) class. This allows the custom data source to undergo sorting based on the criteria specified in the incoming [DataManagerRequest](https://help.syncfusion.com/cr/blazor/Syncfusion.Blazor.DataManagerRequest.html) object. + +{% highlight razor %} +[HttpPost] +[Route("api/[controller]")] +public object Post([FromBody] DataManagerRequest DataManagerRequest) +{ + IEnumerable DataSource = GetOrderData(); + // Handling Sorting in Url Adaptor. + if (DataManagerRequest.Sorted != null && DataManagerRequest.Sorted.Count > 0) + { + // Sorting + DataSource = DataOperations.PerformSorting(DataSource, DataManagerRequest.Sorted); + //Add custom logic here if needed and remove above method + } + int count = DataSource.Cast().Count(); + return new { result = DataSource, count = count }; +} +{% endhighlight %} + +### Handling aggregate operation + +To handle aggregate operation, ensure that your API endpoint supports custom aggregate criteria. Implement the aggregate logic on the server-side using the [PerformAggregation](https://help.syncfusion.com/cr/blazor/Syncfusion.Blazor.Data.DataUtil.html#Syncfusion_Blazor_Data_DataUtil_PerformAggregation_System_Collections_IEnumerable_System_Collections_Generic_List_Syncfusion_Blazor_Data_Aggregate__) method from the [DataUtil](https://help.syncfusion.com/cr/blazor/Syncfusion.Blazor.Data.DataUtil.html) class. This allows the custom data source to undergo aggregate based on the criteria specified in the incoming [DataManagerRequest](https://help.syncfusion.com/cr/blazor/Syncfusion.Blazor.DataManagerRequest.html) object. + +{% highlight razor %} + [HttpPost] + [Route("api/[controller]")] + public object Post([FromBody] DataManagerRequest DataManagerRequest) + { + IEnumerable DataSource = GetOrderData(); + int count = DataSource.Cast().Count(); + // Handling Aggregation in Url Adaptor. + IDictionary Aggregates = null; + if (DataManagerRequest.Aggregates != null) + { + // Aggregation + Aggregates = DataUtil.PerformAggregation(DataSource, DataManagerRequest.Aggregates); + //Add custom logic here if needed and remove above method + } + return new { result = DataSource, count = count, aggregates = Aggregates }; + } +{% endhighlight %} + +### Handling paging operation + +To handle paging operation, ensure that your API endpoint supports custom paging criteria. Implement the paging logic on the server-side using the [PerformTake](https://help.syncfusion.com/cr/blazor/Syncfusion.Blazor.DataOperations.html#Syncfusion_Blazor_DataOperations_PerformTake_System_Collections_IEnumerable_System_Int32_) and [PerformSkip](https://help.syncfusion.com/cr/blazor/Syncfusion.Blazor.DataOperations.html#Syncfusion_Blazor_DataOperations_PerformSkip__1_System_Collections_Generic_IEnumerable___0__System_Int32_) method from the [DataOperations](https://help.syncfusion.com/cr/blazor/Syncfusion.Blazor.DataOperations.html) class. This allows the custom data source to undergo paging based on the criteria specified in the incoming [DataManagerRequest](https://help.syncfusion.com/cr/blazor/Syncfusion.Blazor.DataManagerRequest.html) object. + +{% highlight razor %} +[HttpPost] +[Route("api/[controller]")] +public object Post([FromBody] DataManagerRequest DataManagerRequest) +{ + IEnumerable DataSource = GetOrderData(); + int count = DataSource.Cast().Count(); + // Handling Paging in Url Adaptor. + if (DataManagerRequest.Skip != 0) + { + // Paging + DataSource = DataOperations.PerformSkip(DataSource, DataManagerRequest.Skip); + //Add custom logic here if needed and remove above method + } + if (DataManagerRequest.Take != 0) + { + DataSource = DataOperations.PerformTake(DataSource, DataManagerRequest.Take); + //Add custom logic here if needed and remove above method + } + return new { result = DataSource, count = count }; +} +{% endhighlight %} + +> For optimal performance, it is recommended to follow this sequence of operations(Searching, Filtering, Sorting, Aggregate, Paging and Grouping ) in the [ReadAsync](https://help.syncfusion.com/cr/blazor/Syncfusion.Blazor.DataAdaptor.html#Syncfusion_Blazor_DataAdaptor_ReadAsync_Syncfusion_Blazor_DataManagerRequest_System_String_) method. + +### Handling CRUD operations + +To enable editing in this Blazor DataGrid component, utilize the [GridEditSettings](https://help.syncfusion.com/cr/blazor/Syncfusion.Blazor.Grids.GridEditSettings.html) component. The Blazor DataGrid offers multiple edit modes including the [Inline/Normal](https://blazor.syncfusion.com/documentation/datagrid/in-line-editing), [Dialog](https://blazor.syncfusion.com/documentation/datagrid/dialog-editing), and [Batch](https://blazor.syncfusion.com/documentation/datagrid/batch-editing) editing. For more details, refer to the Blazor DataGrid component [editing](https://blazor.syncfusion.com/documentation/datagrid/editing) documentation. + +In this scenario, the inline edit mode and [Toolbar](https://blazor.syncfusion.com/documentation/datagrid/tool-bar) property are configured to display toolbar items for editing purposes. + +{% tabs %} +{% highlight razor %} + + + + + + + + + + + +{% endhighlight %} +{% endtabs %} + +> * Normal editing is the default edit mode for the Blazor DataGrid component. To enable CRUD operations, ensure that the [IsPrimaryKey](https://help.syncfusion.com/cr/blazor/Syncfusion.Blazor.Grids.GridColumn.html#Syncfusion_Blazor_Grids_GridColumn_IsPrimaryKey) property is set to **true** for a specific `GridColumn`, ensuring that its value is unique. +> * If database has an Autogenerated column, ensure to define [IsIdentity](https://help.syncfusion.com/cr/blazor/Syncfusion.Blazor.Grids.GridColumn.html#Syncfusion_Blazor_Grids_GridColumn_IsIdentity) property of `GridColumn` to disable them during adding or editing operations. + +**Insert Operation:** + +To insert a new row, simply click the **Add** toolbar button. The new record edit form will be displayed as shown below. Upon clicking the **Update** toolbar button, record will inserted into the Orders table by calling the following **POST** method of an API. + +{% tabs %} +{% highlight c# tabtitle="OrdersController.cs" %} +[HttpPost] +[Route("api/Grid/Insert")] +/// +/// Inserts a new data item into the data collection. +/// +/// The set of information along with new record detail which is need to be inserted. +/// Returns void +public void Insert([FromBody] CRUDModel Value) +{ + //TODO: Enter the connectionstring of database + string ConnectionString = @""; + //Create query to insert the specific into the database by accessing its properties + string Query = $"Insert into Orders(OrderID, CustomerName,Freight,ShipCity,EmployeeID) values( '{Value.Value.OrderID}','{Value.Value.CustomerName}','{Value.Value.Freight}','{Value.Value.ShipCity}','{Value.Value.EmployeeID}')"; + MySqlConnection Connection = new MySqlConnection(ConnectionString); + Connection.Open(); + MySqlCommand Command = new MySqlCommand(Query, Connection); + //Execute this code to reflect the changes into the database + Command.ExecuteNonQuery(); + Connection.Close(); + //Add custom logic here if needed and remove above method +} +{% endhighlight %} +{% endtabs %} + +**Update Operation:** + +To edit a row, first select desired row and click the **Edit** toolbar button. The edit form will be displayed and proceed to modify any column value as per your requirement. Clicking the **Update** toolbar button will update the edit record in the Orders table by involving the following **Post** method of an API. + +{% tabs %} +{% highlight c# tabtitle="OrdersController.cs" %} +[HttpPost] +[Route("api/Grid/Update")] +/// +/// Update a existing data item from the data collection. +/// +/// The set of information along with updated record detail which is need to be updated. +/// Returns void +public void Update([FromBody] CRUDModel Value) +{ + //TODO: Enter the connectionstring of database + string ConnectionString = @""; + //Create query to update the changes into the database by accessing its properties + string Query = $"Update Orders set CustomerName='{Value.Value.CustomerName}', Freight='{Value.Value.Freight}',EmployeeID='{Value.Value.EmployeeID}',ShipCity='{Value.Value.ShipCity}' where OrderID='{Value.Value.OrderID}'"; + MySqlConnection Connection = new MySqlConnection(ConnectionString); + Connection.Open(); + //Execute the MySQL Command + MySqlCommand Command = new MySqlCommand(Query, Connection); + //Execute this code to reflect the changes into the database + Command.ExecuteNonQuery(); + Connection.Close(); + //Add custom logic here if needed and remove above method +} +{% endhighlight %} +{% endtabs %} + +**Delete Operation:** + +To delete a row, simply select the desired row and click the **Delete** toolbar button. This action will trigger a **DELETE** request to an API, containing the primary key value of the selected record. As a result corresponding record will be removed from the Orders table. + +{% tabs %} +{% highlight c# tabtitle="OrdersController.cs" %} + [HttpPost] +[Route("api/Grid/Delete")] +/// +/// Remove a specific data item from the data collection. +/// +/// The set of information along with specific record detail which is need to be removed. +/// Returns void +public void Delete([FromBody] CRUDModel Value) +{ + //TODO: Enter the connectionstring of database + string ConnectionString = @""; + //Create query to remove the specific from database by passing the primary key column value. + string Query = $"Delete from Orders where OrderID={Value.Key}"; + MySqlConnection Connection = new MySqlConnection(ConnectionString); + Connection.Open(); + //Execute the MySQL Command + MySqlCommand Command = new MySqlCommand(Query, Connection); + //Execute this code to reflect the changes into the database + Command.ExecuteNonQuery(); + Connection.Close(); + //Add custom logic here if needed and remove above method +} +{% endhighlight %} +{% endtabs %} + +**Batch Operation:** + +To perform batch operation, define the edit [Mode](https://help.syncfusion.com/cr/blazor/Syncfusion.Blazor.Grids.GridEditSettings.html#Syncfusion_Blazor_Grids_GridEditSettings_Mode) as `Batch` and specify the [BatchUrl](https://help.syncfusion.com/cr/blazor/Syncfusion.Blazor.DataManager.html#Syncfusion_Blazor_DataManager_BatchUrl) property in the `SfDataManager`. Use the **Add** toolbar button to insert new row in batch editing mode. To edit a cell, double-click the desired cell and update the value as required. To delete a record, simply select the record and press the **Delete** toolbar button. Now, all CRUD operations will be executed in batch editing mode. Clicking the **Update** toolbar button will update the newly added, edited, or deleted records from the Orders table using a single API **POST** request. + +{% highlight razor %} + [HttpPost] +[Route("api/Grid/Batch")] +/// +/// Batchupdate (Insert, Update, Delete) a collection of datas item from the data collection. +/// +/// The set of information along with details about the CRUD actions to be executed from the database. +/// Returns void +public void Batch([FromBody] CRUDModel Value) +{ + //TODO: Enter the connectionstring of database + string ConnectionString = @""; + if (Value.Changed != null) + { + foreach (var Record in (IEnumerable)Value.Changed) + { + //Create query to update the changes into the database by accessing its properties + string Query = $"Update Orders set CustomerName='{Record.CustomerName}', Freight='{Record.Freight}',EmployeeID='{Record.EmployeeID}',ShipCity='{Record.ShipCity}' where OrderID='{Record.OrderID}'"; + MySqlConnection Connection = new MySqlConnection(ConnectionString); + Connection.Open(); + //Execute the MySQL Command + MySqlCommand Command = new MySqlCommand(Query, Connection); + //Execute this code to reflect the changes into the database + Command.ExecuteNonQuery(); + Connection.Close(); + //Add custom logic here if needed and remove above method + } + + } + if (Value.Added != null) + { + foreach (var Record in (IEnumerable)Value.Added) + { + //Create query to insert the specific into the database by accessing its properties + string Query = $"Insert into Orders(CustomerName,Freight,ShipCity,EmployeeID) values('{Record.CustomerName}','{Record.Freight}','{Record.ShipCity}','{Record.EmployeeID}')"; + MySqlConnection Connection = new MySqlConnection(ConnectionString); + Connection.Open(); + //Execute the MySQL Command + MySqlCommand Command = new MySqlCommand(Query, Connection); + //Execute this code to reflect the changes into the database + Command.ExecuteNonQuery(); + Connection.Close(); + //Add custom logic here if needed and remove above method + } + } + if (Value.Deleted != null) + { + foreach (var Record in (IEnumerable)Value.Deleted) + { + //Create query to remove the specific from database by passing the primary key column value. + string Query = $"Delete from Orders where OrderID={Record.OrderID}"; + MySqlConnection Connection = new MySqlConnection(ConnectionString); + Connection.Open(); + //Execute the MySQL Command + MySqlCommand Command = new MySqlCommand(Query, Connection); + //Execute this code to reflect the changes into the database + Command.ExecuteNonQuery(); + Connection.Close(); + //Add custom logic here if needed and remove above method + } + } +} +{% endhighlight %} + +When you run the application, the resultant Blazor DataGrid component will look like this + +![Blazor DataGrid component bound with MySQL Server data](../images/blazor-Grid-Ms-SQl-databinding-Gif.gif) + +> Find the sample from this [GitHub location](). + +## Binding data from MySQL Server using CustomAdaptor + +This section describes step by step process how to retrieve data from a MySQL server using `CustomAdaptor` and bind it to the Blazor DataGrid component. + +**1.** To create a simple Blazor DataGrid component, the procedure is explained in the above-mentioned topic on [Connecting Blazor DataGrid to an API service](#connecting-blazor-datagrid-to-an-api-service) + +> * In this Blazor Web app, set the `rendermode` as either **InteractiveServer** or **InteractiveAuto** as per your configuration. + +**2.** To connect a MySQL Server database using the MySQL driver in your application, you need to install the [MySQL.Data](https://www.nuget.org/packages/MySql.Data) NuGet package. To add **MySQL.Data** in the app, open the NuGet package manager in Visual Studio (Tools → NuGet Package Manager → Manage NuGet Packages for Solution), search and install it. + +**3.** If you intend to inject your own service into the `CustomAdaptor` and utilize it, you can achieve this as follows. + +{% tabs %} +{% highlight razor tabtitle="Index.razor" %} +@rendermode InteractiveServer + +@using Syncfusion.Blazor.Grids +@using Syncfusion.Blazor.Data +@using Syncfusion.Blazor +@using MySql.Data.MySqlClient; + + + + + + + + + + @{ + var aggregate = (context as AggregateTemplateContext); +
    +

    Sum: @aggregate.Sum

    +
    + } +
    +
    +
    +
    + + + + + @{ + var aggregate = (context as AggregateTemplateContext); +
    +

    Average: @aggregate.Average

    +
    + } +
    +
    +
    +
    +
    + + + + + + + +
    + +@code { + SfGrid Grid { get; set; } +} +{% endhighlight %} +{% highlight razor tabtitle="Orderdata.cs"%} + public class Order + { + public int? OrderID { get; set; } + public string CustomerName { get; set; } + public int EmployeeID { get; set; } + public decimal Freight { get; set; } + public string ShipCity { get; set; } + } +{% endhighlight %} +{% endtabs %} + +**4.** Within the `CustomAdaptor’s` [ReadAsync](https://help.syncfusion.com/cr/blazor/Syncfusion.Blazor.DataAdaptor.html#Syncfusion_Blazor_DataAdaptor_ReadAsync_Syncfusion_Blazor_DataManagerRequest_System_String_) method, fetch the data from the service by calling the `GetOrdersAsync` method. + +* In this `GetOrdersAsync` method, the MySQL Server database data is fetch by using the **MySqlDataAdapter** class. + +* Employ the **Fill** method of the **DataAdapter** to populate a **DataSet** with the results of the `Select` command of the **DataAdapter**, followed by conversion of the **DataSet** into a List. + +* Finally, return the response as a `Result` and `Count` pair object in the `ReadAsync` method to bind the data to the Blazor DataGrid component. + +{% tabs %} +{% highlight razor tabtitle="Index.razor" %} +@rendermode InteractiveServer + +@using Syncfusion.Blazor.Grids +@using Syncfusion.Blazor.Data +@using Syncfusion.Blazor +@using MySql.Data.MySqlClient; +@using System.Collections + + + + + + + + + + @{ + var aggregate = (context as AggregateTemplateContext); +
    +

    Sum: @aggregate.Sum

    +
    + } +
    +
    +
    +
    + + + + + @{ + var aggregate = (context as AggregateTemplateContext); +
    +

    Average: @aggregate.Average

    +
    + } +
    +
    +
    +
    +
    + + + + + + + +
    + +@code { + /// + /// Implementing custom adaptor by extending the class. + /// The Blazor DataGrid component support for custom data binding, which enables the binding and manipulation of data in a personalized way, using user-defined methods. + /// + public class CustomAdaptor : DataAdaptor + { + public OrderData OrderService = new OrderData(); + /// + /// Returns the data collection after performing data operations based on request from + /// + /// DataManagerRequest contains the information regarding searching, filtering, sorting, aggregates paging and grouping which is handled on the Blazor DataGrid component side + /// An optional parameter that can be used to perform additional data operations. + /// The data collection's type is determined by how this method has been implemented. + public override async Task ReadAsync(DataManagerRequest DataManagerRequest, string Key = null) + { + IEnumerable DataSource = await OrderService.GetOrdersAsync(); + int count = DataSource.Cast().Count(); + return DataManagerRequest.RequiresCounts ? new DataResult() { Result = DataSource, Count = count } : (object)DataSource; + } + } +} +{% endhighlight %} +{% highlight razor tabtitle="OrderData.cs" %} +public class OrderData +{ + public async Task> GetOrdersAsync() + { + //Create query to fetch data from database + string Query = "SELECT * FROM orders ORDER BY OrderID;"; + List Orders = null; + //Create SQL Connection + using (MySqlConnection Connection = new MySqlConnection(ConnectionString)) + { + //Using MySqlDataAdapter and Query create connection with database + MySqlDataAdapter adapter = new MySqlDataAdapter(Query, Connection); + DataSet data = new DataSet(); + Connection.Open(); + // Using MySqlDataAdapter, process the query string and fill the data into the dataset + adapter.Fill(data); + //Cast the data fetched from Adapter to List + Orders = data.Tables[0].AsEnumerable().Select(r => new Order + { + OrderID = r.Field("OrderID"), + CustomerName = r.Field("CustomerName"), + EmployeeID = r.Field("EmployeeID"), + ShipCity = r.Field("ShipCity"), + Freight = r.Field("Freight") + }).ToList(); + Connection.Close(); + } + return Orders; + } +} +{% endhighlight %} +{% endtabs %} + +> * The `DataManagerRequest` encompasses details about the Blazor DataGrid component actions such as searching, filtering, sorting, aggregate, paging and grouping. +> * In the above Blazor DataGrid, [AllowSearching](https://help.syncfusion.com/cr/blazor/Syncfusion.Blazor.Grids.GridColumn.html#Syncfusion_Blazor_Grids_GridColumn_AllowSearching), [AllowSorting](https://help.syncfusion.com/cr/blazor/Syncfusion.Blazor.Grids.SfGrid-1.html#Syncfusion_Blazor_Grids_SfGrid_1_AllowSorting), [AllowFiltering](https://help.syncfusion.com/cr/blazor/Syncfusion.Blazor.Grids.SfGrid-1.html#Syncfusion_Blazor_Grids_SfGrid_1_AllowFiltering), [AllowPaging](https://help.syncfusion.com/cr/blazor/Syncfusion.Blazor.Grids.SfGrid-1.html#Syncfusion_Blazor_Grids_SfGrid_1_AllowPaging), [AllowGrouping](https://help.syncfusion.com/cr/blazor/Syncfusion.Blazor.Grids.SfGrid-1.html#Syncfusion_Blazor_Grids_SfGrid_1_AllowGrouping) and CRUD-related properties have been enabled. The details on how to handle these actions are explained below. + +When the application is executed, the Blazor DataGrid component will appear as depicted below. + +![Blazor DataGrid component bound with MySQL Server data](../images/blazor-Grid-Ms-SQL-databinding.png) + +### Handling searching operation + +When utilizing the `CustomAdaptor`, managing the searching operation involves overriding the [Read](https://help.syncfusion.com/cr/blazor/Syncfusion.Blazor.DataAdaptor.html#Syncfusion_Blazor_DataAdaptor_Read_Syncfusion_Blazor_DataManagerRequest_System_String_) or [ReadAsync](https://help.syncfusion.com/cr/blazor/Syncfusion.Blazor.DataAdaptor.html#Syncfusion_Blazor_DataAdaptor_ReadAsync_Syncfusion_Blazor_DataManagerRequest_System_String_) method of the [DataAdaptor](https://help.syncfusion.com/cr/blazor/Syncfusion.Blazor.DataAdaptor.html) abstract class. + +In the code example below, searching a custom data source can be accomplished by employing the built-in [PerformSearching](https://help.syncfusion.com/cr/blazor/Syncfusion.Blazor.DataOperations.html#Syncfusion_Blazor_DataOperations_PerformSearching_System_Collections_IEnumerable_System_Collections_Generic_List_Syncfusion_Blazor_Data_SearchFilter__) method of the [DataOperations](https://help.syncfusion.com/cr/blazor/Syncfusion.Blazor.DataOperations.html) class. Alternatively, you can implement your own method for searching operation and bind the resultant data to the Blazor DataGrid component. + +{% highlight razor %} +public class CustomAdaptor : DataAdaptor +{ + public OrderData OrderService = new OrderData(); + // Performs data read operation + public override async Task ReadAsync(DataManagerRequest DataManagerRequest, string Key = null) + { + IEnumerable DataSource = await OrderService.GetOrdersAsync(); + // Handling Searching in Custom Adaptor. + if (DataManagerRequest.Search != null && DataManagerRequest.Search.Count > 0) + { + // Searching + DataSource = DataOperations.PerformSearching(DataSource, DataManagerRequest.Search); + //Add custom logic here if needed and remove above method + } + int count = DataSource.Cast().Count(); + return DataManagerRequest.RequiresCounts ? new DataResult() { Result = DataSource, Count = count } : (object)DataSource; + } +} +{% endhighlight %} + +### Handling filtering operation + +When employing the `CustomAdaptor`, handling the filtering operation involves overriding the [Read](https://help.syncfusion.com/cr/blazor/Syncfusion.Blazor.DataAdaptor.html#Syncfusion_Blazor_DataAdaptor_Read_Syncfusion_Blazor_DataManagerRequest_System_String_) or [ReadAsync](https://help.syncfusion.com/cr/blazor/Syncfusion.Blazor.DataAdaptor.html#Syncfusion_Blazor_DataAdaptor_ReadAsync_Syncfusion_Blazor_DataManagerRequest_System_String_) method of the [DataAdaptor](https://help.syncfusion.com/cr/blazor/Syncfusion.Blazor.DataAdaptor.html) abstract class. + +In the code example below, filtering a custom data source can be achieved by utilizing the built-in [PerformFiltering](https://help.syncfusion.com/cr/blazor/Syncfusion.Blazor.DataOperations.html#Syncfusion_Blazor_DataOperations_PerformFiltering__1_System_Collections_Generic_IEnumerable___0__System_Collections_Generic_List_Syncfusion_Blazor_Data_WhereFilter__System_String_) method of the [DataOperations](https://help.syncfusion.com/cr/blazor/Syncfusion.Blazor.DataOperations.html) class. Alternatively, you can implement your own method for filtering operation and bind the resulting data to the Blazor DataGrid component. + +{% highlight razor %} +public class CustomAdaptor : DataAdaptor +{ + public OrderData OrderService = new OrderData(); + // Performs data read operation + public override async Task ReadAsync(DataManagerRequest DataManagerRequest, string Key = null) + { + IEnumerable DataSource = await OrderService.GetOrdersAsync(); + // Handling Filtering in Custom Adaptor. + if (DataManagerRequest.Where != null && DataManagerRequest.Where.Count > 0) + { + // Filtering + DataSource = DataOperations.PerformFiltering(DataSource, DataManagerRequest.Where, DataManagerRequest.Where[0].Operator); + //Add custom logic here if needed and remove above method + } + int count = DataSource.Cast().Count(); + return DataManagerRequest.RequiresCounts ? new DataResult() { Result = DataSource, Count = count } : (object)DataSource; + } +} +{% endhighlight %} + +### Handling sorting operation + +When utilizing the `CustomAdaptor`, managing the sorting operation involves overriding the [Read](https://help.syncfusion.com/cr/blazor/Syncfusion.Blazor.DataAdaptor.html#Syncfusion_Blazor_DataAdaptor_Read_Syncfusion_Blazor_DataManagerRequest_System_String_) or [ReadAsync](https://help.syncfusion.com/cr/blazor/Syncfusion.Blazor.DataAdaptor.html#Syncfusion_Blazor_DataAdaptor_ReadAsync_Syncfusion_Blazor_DataManagerRequest_System_String_) method of the [DataAdaptor](https://help.syncfusion.com/cr/blazor/Syncfusion.Blazor.DataAdaptor.html) abstract class. + +In the code example below, sorting a custom data source can be accomplished by employing the built-in [PerformSorting](https://help.syncfusion.com/cr/blazor/Syncfusion.Blazor.DataOperations.html#Syncfusion_Blazor_DataOperations_PerformSorting__1_System_Collections_Generic_IEnumerable___0__System_Collections_Generic_List_Syncfusion_Blazor_Data_Sort__) method of the [DataOperations](https://help.syncfusion.com/cr/blazor/Syncfusion.Blazor.DataOperations.html) class. Alternatively, you can implement your own method for sorting operation and bind the resulting data to the Blazor DataGrid component. + +{% highlight razor %} +public class CustomAdaptor : DataAdaptor +{ + public OrderData OrderService = new OrderData(); + // Performs data read operation + public override async Task ReadAsync(DataManagerRequest DataManagerRequest, string Key = null) + { + IEnumerable DataSource = await OrderService.GetOrdersAsync(); + // Handling Sorting in Custom Adaptor. + if (DataManagerRequest.Sorted != null && DataManagerRequest.Sorted.Count > 0) + { + // Sorting + DataSource = DataOperations.PerformSorting(DataSource, DataManagerRequest.Sorted); + //Add custom logic here if needed and remove above method + } + int count = DataSource.Cast().Count(); + return DataManagerRequest.RequiresCounts ? new DataResult() { Result = DataSource, Count = count } : (object)DataSource; + } +} +{% endhighlight %} + +### Handling aggregate operation + +When employing `CustomAdaptor`, the aggregate operation must be managed within the [Read](https://help.syncfusion.com/cr/blazor/Syncfusion.Blazor.DataAdaptor.html#Syncfusion_Blazor_DataAdaptor_Read_Syncfusion_Blazor_DataManagerRequest_System_String_) or [ReadAsync](https://help.syncfusion.com/cr/blazor/Syncfusion.Blazor.DataAdaptor.html#Syncfusion_Blazor_DataAdaptor_ReadAsync_Syncfusion_Blazor_DataManagerRequest_System_String_) method of the `CustomAdaptor`. + +The provided sample code illustrated how to implement the aggregate operation within `CustomAdaptor`, + +{% highlight razor %} +public class CustomAdaptor : DataAdaptor +{ + public OrderData OrderService = new OrderData(); + // Performs data read operation + public override async Task ReadAsync(DataManagerRequest DataManagerRequest, string Key = null) + { + IEnumerable DataSource = await OrderService.GetOrdersAsync(); + int count = DataSource.Cast().Count(); + // Handling Aggregation in Custom Adaptor. + IDictionary Aggregates = null; + if (DataManagerRequest.Aggregates != null) // Aggregation + { + Aggregates = DataUtil.PerformAggregation(DataSource, DataManagerRequest.Aggregates); + //Add custom logic here if needed and remove above method + } + return DataManagerRequest.RequiresCounts ? new DataResult() { Result = DataSource, Count = count, Aggregates = Aggregates } : (object)DataSource; + } +} +{% endhighlight %} + +### Handling paging operation + +When employing the `CustomAdaptor`, handling paging operation involves overriding the [Read](https://help.syncfusion.com/cr/blazor/Syncfusion.Blazor.DataAdaptor.html#Syncfusion_Blazor_DataAdaptor_Read_Syncfusion_Blazor_DataManagerRequest_System_String_) or [ReadAsync](https://help.syncfusion.com/cr/blazor/Syncfusion.Blazor.DataAdaptor.html#Syncfusion_Blazor_DataAdaptor_ReadAsync_Syncfusion_Blazor_DataManagerRequest_System_String_) method of the [DataAdaptor](https://help.syncfusion.com/cr/blazor/Syncfusion.Blazor.DataAdaptor.html) abstract class. + +In the code example below, paging a custom data source can be achieved by utilizing the built-in [PerformTake](https://help.syncfusion.com/cr/blazor/Syncfusion.Blazor.DataOperations.html#Syncfusion_Blazor_DataOperations_PerformTake_System_Collections_IEnumerable_System_Int32_) and [PerformSkip](https://help.syncfusion.com/cr/blazor/Syncfusion.Blazor.DataOperations.html#Syncfusion_Blazor_DataOperations_PerformSkip__1_System_Collections_Generic_IEnumerable___0__System_Int32_) method of the [DataOperations](https://help.syncfusion.com/cr/blazor/Syncfusion.Blazor.DataOperations.html) class. Alternatively, you can use your own method for paging operation and bind the resulting data to the Blazor DataGrid component. + +{% highlight razor %} +public class CustomAdaptor : DataAdaptor +{ + public OrderData OrderService = new OrderData(); + // Performs data read operation + public override async Task ReadAsync(DataManagerRequest DataManagerRequest, string Key = null) + { + IEnumerable DataSource = await OrderService.GetOrdersAsync(); + int count = DataSource.Cast().Count(); + // Handling paging in Custom Adaptor. + if (DataManagerRequest.Skip != 0) + { + // Paging + DataSource = DataOperations.PerformSkip(DataSource, DataManagerRequest.Skip); + //Add custom logic here if needed and remove above method + } + if (DataManagerRequest.Take != 0) + { + // Taking + DataSource = DataOperations.PerformTake(DataSource, DataManagerRequest.Take); + //Add custom logic here if needed and remove above method + } + return DataManagerRequest.RequiresCounts ? new DataResult() { Result = DataSource, Count = count } : (object)DataSource; + } +} +{% endhighlight %} + +### Handling grouping operation + +When employing `CustomAdaptor`, the grouping operation must be managed within the [Read](https://help.syncfusion.com/cr/blazor/Syncfusion.Blazor.DataAdaptor.html#Syncfusion_Blazor_DataAdaptor_Read_Syncfusion_Blazor_DataManagerRequest_System_String_) or [ReadAsync](https://help.syncfusion.com/cr/blazor/Syncfusion.Blazor.DataAdaptor.html#Syncfusion_Blazor_DataAdaptor_ReadAsync_Syncfusion_Blazor_DataManagerRequest_System_String_) method of the `CustomAdaptor`. + +The provided sample code illustrated how to implement the grouping operation within `CustomAdaptor`, + +{% highlight razor %} +public class CustomAdaptor : DataAdaptor +{ + public OrderData OrderService = new OrderData(); + // Performs data read operation + public override async Task ReadAsync(DataManagerRequest DataManagerRequest, string Key = null) + { + IEnumerable DataSource = await OrderService.GetOrdersAsync(); + int count = DataSource.Cast().Count(); + DataResult DataObject = new DataResult(); + // Handling Group operation in Custom Adaptor. + if (DataManagerRequest.Group != null) + { + IEnumerable ResultData = DataSource.ToList(); + // Grouping + foreach (var group in DataManagerRequest.Group) + { + ResultData = DataUtil.Group(ResultData, group, DataManagerRequest.Aggregates, 0, DataManagerRequest.GroupByFormatter); + //Add custom logic here if needed and remove above method + } + DataObject.Result = ResultData; + DataObject.Count = count; + return DataManagerRequest.RequiresCounts ? DataObject : (object)ResultData; + } + return DataManagerRequest.RequiresCounts ? new DataResult() { Result = DataSource, Count = count } : (object)DataSource; + } +} +{% endhighlight %} + +> * For optimal performance, it is recommended to follow this sequence of operations(Searching, Filtering, Sorting, Aggregate, Paging and Grouping) in the `ReadAsync` method. +> * If both grouping and aggregate operations are enabled, the code provided below demonstrates how to implement these operations within the `CustomAdaptor`. + +```cshtml +public class CustomAdaptor : DataAdaptor +{ + public OrderData OrderService = new OrderData(); + // Performs data Read operation + public override async Task ReadAsync(DataManagerRequest DataManagerRequest, string Key = null) + { + IEnumerable DataSource = await OrderService.GetOrdersAsync(); + int count = DataSource.Cast().Count(); + DataResult DataObject = new DataResult(); + // Handling both Grouping and Aggregation in Custom Adaptor. + if (DataManagerRequest.Aggregates != null || DataManagerRequest.Group != null) // Aggregation + { + if (DataManagerRequest.Group != null) + { + IEnumerable ResultData = DataSource.ToList(); + // Grouping + foreach (var group in DataManagerRequest.Group) + { + ResultData = DataUtil.Group(ResultData, group, DataManagerRequest.Aggregates, 0, DataManagerRequest.GroupByFormatter); + //Add custom logic here if needed and remove above method + } + DataObject.Result = ResultData; + } + else + { + DataObject.Result = DataSource; + } + DataObject.Count = count; + DataObject.Aggregates = DataUtil.PerformAggregation(DataSource, DataManagerRequest.Aggregates); + + return DataManagerRequest.RequiresCounts ? DataObject : (object)DataSource; + } + return DataManagerRequest.RequiresCounts ? new DataResult() { Result = DataSource, Count = count } : (object)DataSource; + } +} +``` + +### Handling CRUD operations + +To enable editing in the Blazor DataGrid component, utilize the [GridEditSettings](https://help.syncfusion.com/cr/blazor/Syncfusion.Blazor.Grids.GridEditSettings.html) component. The Blazor DataGrid component offers multiple edit modes including the Inline/Normal, Dialog and Batch editing. For more details, refer to the Blazor DataGrid component [editing](https://blazor.syncfusion.com/documentation/datagrid/editing) documentation. + +In this scenario, the inline edit mode and [Toolbar](https://blazor.syncfusion.com/documentation/datagrid/tool-bar) property configured to display toolbar items for editing purpose. + +{% highlight razor %} + + + + + + + + + + + +{% endhighlight %} + +> * Normal editing is the default edit mode for the Blazor DataGrid component. To enable CRUD operations, ensure that the [IsPrimaryKey](https://help.syncfusion.com/cr/blazor/Syncfusion.Blazor.Grids.GridColumn.html#Syncfusion_Blazor_Grids_GridColumn_IsPrimaryKey) property is set to **true** for a specific `GridColumn`, ensuring that its value is unique. +> * If database has an Autogenerated column, ensure to define [IsIdentity](https://help.syncfusion.com/cr/blazor/Syncfusion.Blazor.Grids.GridColumn.html#Syncfusion_Blazor_Grids_GridColumn_IsIdentity) property of `GridColumn` to disable them during adding or editing operations. + +The CRUD operations can be performed and customized on our own by overriding the following CRUD methods of the [DataAdaptor](https://help.syncfusion.com/cr/blazor/Syncfusion.Blazor.DataAdaptor.html) abstract class. + +* Insert/InsertAsync +* Remove/RemoveAsync +* Update/UpdateAsync +* BatchUpdate/BatchUpdateAsync + +Let’s see how to perform CRUD operation using MySQL Server data with Syncfusion Blazor DataGrid component. + +**Insert Operation:** + +To execute the insert operation, you will need to override the [Insert](https://help.syncfusion.com/cr/blazor/Syncfusion.Blazor.DataAdaptor.html#Syncfusion_Blazor_DataAdaptor_Insert_Syncfusion_Blazor_DataManager_System_Object_System_String_) or [InsertAsync](https://help.syncfusion.com/cr/blazor/Syncfusion.Blazor.DataAdaptor.html#Syncfusion_Blazor_DataAdaptor_InsertAsync_Syncfusion_Blazor_DataManager_System_Object_System_String_) method of the `CustomAdaptor`. Then, integrate the following code snippet into the `CustomAdaptor` class. The below code snippet demonstrated how to handle the insertion of new records within the `InsertAsync` method of `CustomAdaptor` component. Modify the logic within this method according to the requirements of your application. + +{% tabs %} +{% highlight razor tabtitle="Index.razor"%} +/// +/// Inserts a new data item into the data collection. +/// +/// The DataManager is a data management component used for performing data operations in application. +/// The new record which is need to be inserted. +/// An optional parameter that can be used to perform additional data operations. +/// Returns the newly inserted record details. +public override async Task InsertAsync(DataManager DataManager, object Value, string Key) +{ + // Add your insert logic here + // This method will be invoked when inserting new records into the Blazor DataGrid component. + await OrderService.AddOrderAsync(Value as Order); + return Value; +} +{% endhighlight %} +{% highlight razor tabtitle="Orderdata.cs"%} + public async Task AddOrderAsync(Order Value) + { + //Create query to insert the specific into the database by accessing its properties + string Query = $"Insert into Orders(OrderID,CustomerName,Freight,ShipCity,EmployeeID) values('{(Value as Order).OrderID}','{(Value as Order).CustomerName}','{(Value as Order).Freight}','{(Value as Order).ShipCity}','{(Value as Order).EmployeeID}')"; + MySqlConnection Connection = new MySqlConnection(ConnectionString); + Connection.Open(); + //Execute the MySQL Command + MySqlCommand Command = new MySqlCommand(Query, Connection); + //Execute this code to reflect the changes into the database + Command.ExecuteNonQuery(); + Connection.Close(); + } +{% endhighlight %} +{% endtabs %} + +**Update Operation:** + +To execute the update operation, override the [Update](https://help.syncfusion.com/cr/blazor/Syncfusion.Blazor.DataAdaptor.html#Syncfusion_Blazor_DataAdaptor_Update_Syncfusion_Blazor_DataManager_System_Object_System_String_System_String_) or [UpdateAsync](https://help.syncfusion.com/cr/blazor/Syncfusion.Blazor.DataAdaptor.html#Syncfusion_Blazor_DataAdaptor_UpdateAsync_Syncfusion_Blazor_DataManager_System_Object_System_String_System_String_) method of the `CustomAdaptor`. Then, integrate the following code snippet into the `CustomAdaptor` class. The below code snippet demonstrated how to handle the updating of existing records within the `UpdateAsync` method of the `CustomAdaptor` component. Modify the logic within this method according to the requirements of your application. + +{% tabs %} +{% highlight razor tabtitle="Index.razor"%} +/// +/// Updates an existing data item in the data collection. +/// +/// The DataManager is a data management component used for performing data operations in application. +/// The modified record which is need to be updated. +/// The primary column name specifies the field name of the primary column. +/// An optional parameter that can be used to perform additional data operations. +/// Returns the updated data item. +public override async Task UpdateAsync(DataManager DataManager, object Value, string KeyField, string Key) +{ + // Add your update logic here + // This method will be invoked when updating existing records in the Blazor DataGrid component. + await OrderService.UpdateOrderAsync(Value as Order); + return Value; +} +{% endhighlight %} +{% highlight razor tabtitle="Orderdata.cs"%} +public async Task UpdateOrderAsync(Order Value) +{ + //Create query to update the changes into the database by accessing its properties + string Query = $"Update Orders set CustomerName='{(Value as Order).CustomerName}', Freight='{(Value as Order).Freight}',EmployeeID='{(Value as Order).EmployeeID}',ShipCity='{(Value as Order).ShipCity}' where OrderID='{(Value as Order).OrderID}'"; + MySqlConnection Connection = new MySqlConnection(ConnectionString); + Connection.Open(); + //Execute the MySQL Command + MySqlCommand Command = new MySqlCommand(Query, Connection); + //Execute this code to reflect the changes into the database + Command.ExecuteNonQuery(); + Connection.Close(); +} +{% endhighlight %} +{% endtabs %} + +**Delete Operation:** + +To perform the delete operation, you need to override the [Remove](https://help.syncfusion.com/cr/blazor/Syncfusion.Blazor.DataAdaptor.html#Syncfusion_Blazor_DataAdaptor_Remove_Syncfusion_Blazor_DataManager_System_Object_System_String_System_String_) or [RemoveAsync](https://help.syncfusion.com/cr/blazor/Syncfusion.Blazor.DataAdaptor.html#Syncfusion_Blazor_DataAdaptor_RemoveAsync_Syncfusion_Blazor_DataManager_System_Object_System_String_System_String_) method of the `CustomAdaptor`. Below is the code snippet that you can add to `CustomAdaptor` class. The below code snippet demonstrated how to handle the deletion of existing records within the `RemoveAsync` method of `CustomAdaptor` component. Modify the logic within this method according to the requirements of your application. + +{% tabs %} +{% highlight razor tabtitle="Index.razor"%} +/// +/// Removes a data item from the data collection. +/// +/// The DataManager is a data management component used for performing data operations in application. +/// The Value specifies the primary column value which is needs to be removed from the grid record. +/// The KeyField specifies the field name of the primary column. +/// An optional parameter that can be used to perform additional data operations. +/// Returns the removed data item. +public override async Task RemoveAsync(DataManager DataManager, object Value, string KeyField, string Key) +{ + // Add your delete logic here + // This method will be invoked when deleting existing records from the Blazor DataGrid component. + await OrderService.RemoveOrderAsync(Value as int?); + return Value; +} +{% endhighlight %} +{% highlight razor tabtitle="Orderdata.cs"%} +public async Task RemoveOrderAsync(int? Key) +{ + //Create query to remove the specific from database by passing the primary key column value. + string Query = $"Delete from Orders where OrderID={Key}"; + MySqlConnection Connection = new MySqlConnection(ConnectionString); + Connection.Open(); + //Execute the MySQL Command + MySqlCommand Command = new MySqlCommand(Query, Connection); + //Execute this code to reflect the changes into the database + Command.ExecuteNonQuery(); + Connection.Close(); +} +{% endhighlight %} +{% endtabs %} + +**Batch Operation:** + +To perform the batch operation, override the [BatchUpdate](https://help.syncfusion.com/cr/blazor/Syncfusion.Blazor.DataAdaptor.html#Syncfusion_Blazor_DataAdaptor_BatchUpdate_Syncfusion_Blazor_DataManager_System_Object_System_Object_System_Object_System_String_System_String_System_Nullable_System_Int32__) or [BatchUpdateAsync](https://help.syncfusion.com/cr/blazor/Syncfusion.Blazor.DataAdaptor.html#Syncfusion_Blazor_DataAdaptor_BatchUpdateAsync_Syncfusion_Blazor_DataManager_System_Object_System_Object_System_Object_System_String_System_String_System_Nullable_System_Int32__) method of the `CustomAdaptor` and add the following code in the `CustomAdaptor`. The below code snippet demonstrated how to handle the batch update request within the `BatchUpdateAsync` method of `CustomAdaptor` component. Modify the logic within this method according to the requirements of your application. + +{% highlight razor %} +/// +/// /// Batchupdate (Insert, Update, Delete) a collection of data item from the data collection. +/// +/// The DataManager is a data management component used for performing data operations in application. +/// The Changed specifies the collection of record updated in batch mode which needs to be updated from the grid record. +/// The Added specifies the collection of record inserted in batch mode which needs to be inserted from the grid record. +/// The Deleted specifies the collection of record deleted in batch mode which needs to be removed from the grid record. +/// The KeyField specifies the field name of the primary column. +/// An optional parameter that can be used to perform additional data operations. +/// An optional parameter that can be used to perform row drag and drop operation. +/// Returns the removed data item. +public override async Task BatchUpdateAsync(DataManager DataManager, object Changed, object Added, object Deleted, string KeyField, string Key, int? DropIndex) +{ + if (Changed != null) + { + foreach (var record in (IEnumerable)Changed) + { + await OrderService.UpdateOrderAsync(record as Order); + } + } + if (Added != null) + { + foreach (var record in (IEnumerable)Added) + { + await OrderService.AddOrderAsync(record as Order); + } + } + if (Deleted != null) + { + foreach (var record in (IEnumerable)Deleted) + { + await OrderService.RemoveOrderAsync((record as Order).OrderID); + } + } + return Key; +} +{% endhighlight %} + +![Blazor DataGrid component bound with MySQL Server data](../images/blazor-Grid-Ms-SQl-databinding-Gif.gif) + +> You can find the sample in this [GitHub location](). From 8a8af9a4a9c5da8bb329e14bb30118642671a40c Mon Sep 17 00:00:00 2001 From: Naveen Date: Thu, 7 Mar 2024 12:12:50 +0530 Subject: [PATCH 2/5] MYSQL-Data-Binding-Documentation(871699) --- .../connecting-to-database/mysql-server.md | 21 ++++++++++++------- 1 file changed, 14 insertions(+), 7 deletions(-) diff --git a/blazor/datagrid/connecting-to-database/mysql-server.md b/blazor/datagrid/connecting-to-database/mysql-server.md index b2541e46a7..1fe0f56740 100644 --- a/blazor/datagrid/connecting-to-database/mysql-server.md +++ b/blazor/datagrid/connecting-to-database/mysql-server.md @@ -70,15 +70,15 @@ namespace MySqlWebService.Controllers string QueryStr = "SELECT * FROM orders ORDER BY OrderID"; MySqlConnection sqlConnection = new(ConnectionString); sqlConnection.Open(); - //Execute the MySQL Command + //Initialize the MySqlCommand MySqlCommand SqlCommand = new(QueryStr, sqlConnection); - //Using MySqlDataAdapter and Query create connection with database + //Initialize the MySqlDataAdapter MySqlDataAdapter DataAdapter = new(SqlCommand); DataTable DataTable = new(); // Using MySqlDataAdapter, process the query string and fill the data into the dataset DataAdapter.Fill(DataTable); sqlConnection.Close(); - //Cast the data fetched from Adaptor to List + //Cast the data fetched from Adapter to List var DataSource = (from DataRow Data in DataTable.Rows select new Order() { @@ -187,7 +187,7 @@ The theme stylesheet and script can be accessed from NuGet through [Static Web A @using Syncfusion.Blazor.Data @using Syncfusion.Blazor - + @@ -261,35 +261,42 @@ public class GridController : ControllerBase { // Searching DataSource = DataOperations.PerformSearching(DataSource, DataManagerRequest.Search); + //Add custom logic here if needed and remove above method } // Handling Filtering in Url Adaptor. if (DataManagerRequest.Where != null && DataManagerRequest.Where.Count > 0) { // Filtering DataSource = DataOperations.PerformFiltering(DataSource, DataManagerRequest.Where, DataManagerRequest.Where[0].Operator); + //Add custom logic here if needed and remove above method } // Handling Sorting in Url Adaptor. if (DataManagerRequest.Sorted != null && DataManagerRequest.Sorted.Count > 0) { // Sorting DataSource = DataOperations.PerformSorting(DataSource, DataManagerRequest.Sorted); + //Add custom logic here if needed and remove above method } int count = DataSource.Cast().Count(); // Handling Aggregation in Url Adaptor. IDictionary Aggregates = null; - if (DataManagerRequest.Aggregates != null) // Aggregation + if (DataManagerRequest.Aggregates != null) { + //Aggregation Aggregates = DataUtil.PerformAggregation(DataSource, DataManagerRequest.Aggregates); + //Add custom logic here if needed and remove above method } // Handling paging in Url Adaptor. if (DataManagerRequest.Skip != 0) { // Paging DataSource = DataOperations.PerformSkip(DataSource, DataManagerRequest.Skip); + //Add custom logic here if needed and remove above method } if (DataManagerRequest.Take != 0) { DataSource = DataOperations.PerformTake(DataSource, DataManagerRequest.Take); + //Add custom logic here if needed and remove above method } //Here RequiresCount is passed from the control side itself, where ever the ondemand data fetching is needed then the RequiresCount is set as true in component side itself. // In the above case we are using Paging so data are loaded in ondemand bases whenever the next page is clicked in DataGrid side. @@ -640,7 +647,7 @@ This section describes step by step process how to retrieve data from a MySQL se @using Syncfusion.Blazor @using MySql.Data.MySqlClient; - + @@ -716,7 +723,7 @@ This section describes step by step process how to retrieve data from a MySQL se @using MySql.Data.MySqlClient; @using System.Collections - + From dd8e256dc76f347be32a3a7e1545de1555620134 Mon Sep 17 00:00:00 2001 From: Naveen Date: Thu, 7 Mar 2024 15:52:33 +0530 Subject: [PATCH 3/5] MYSQL-Data-Binding-Documentation(871699) --- blazor/datagrid/connecting-to-database/mysql-server.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/blazor/datagrid/connecting-to-database/mysql-server.md b/blazor/datagrid/connecting-to-database/mysql-server.md index 1fe0f56740..4d9559e540 100644 --- a/blazor/datagrid/connecting-to-database/mysql-server.md +++ b/blazor/datagrid/connecting-to-database/mysql-server.md @@ -188,7 +188,7 @@ The theme stylesheet and script can be accessed from NuGet through [Static Web A @using Syncfusion.Blazor - + From 64f2a39bdb135ba0fb8a301c0c71ec783f167418 Mon Sep 17 00:00:00 2001 From: MaithiliyK Date: Tue, 12 Mar 2024 12:46:11 +0530 Subject: [PATCH 4/5] Update mysql-server.md --- .../connecting-to-database/mysql-server.md | 74 +++++++++---------- 1 file changed, 37 insertions(+), 37 deletions(-) diff --git a/blazor/datagrid/connecting-to-database/mysql-server.md b/blazor/datagrid/connecting-to-database/mysql-server.md index 4d9559e540..0f20acfa6c 100644 --- a/blazor/datagrid/connecting-to-database/mysql-server.md +++ b/blazor/datagrid/connecting-to-database/mysql-server.md @@ -1,7 +1,7 @@ --- layout: post -title: MySQL Data Binding in Blazor DataGrid Component | Syncfusion -description: Learn about consuming data from MYSQL Server and binding it to Syncfusion Component, and performing CRUD operations. +title: MySQL Server Data Binding in Blazor DataGrid Component | Syncfusion +description: Learn about consuming data from MySQL Server and binding it to Syncfusion Component, and performing CRUD operations. platform: Blazor control: DataGrid documentation: ug @@ -15,7 +15,7 @@ MySQL Server database can be bound to the Blazor DataGrid component in different * **Using UrlAdaptor** -The [UrlAdaptor](https://blazor.syncfusion.com/documentation/data/adaptors#url-adaptor) serves as the base adaptor for facilitating communication between remote data services and an UI component. It enables the remote binding of data to the Blazor DataGrid component by connecting to an existing pre-configured API service linked to the MySQL Server database. While the Blazor DataGrid component supports various adaptors to fulfill this requirement, including [Web API](https://blazor.syncfusion.com/documentation/data/adaptors#web-api-adaptor), [OData](https://blazor.syncfusion.com/documentation/data/adaptors#odata-adaptor), [ODataV4](https://blazor.syncfusion.com/documentation/data/adaptors#odatav4-adaptor), [Url](https://blazor.syncfusion.com/documentation/data/adaptors#url-adaptor), and [GraphQL](https://blazor.syncfusion.com/documentation/data/adaptors#graphql-service-binding), the `UrlAdaptor` is particularly useful for the scenarios where a custom API service with unique logic for handling data and CRUD operations is in place. This approach allows for custom handling of data and CRUD operations, and the resultant data returned in the `Result` and `Count` format for display in the Blazor DataGrid component. +The [UrlAdaptor](https://blazor.syncfusion.com/documentation/data/adaptors#url-adaptor) serves as the base adaptor for facilitating communication between remote data services and an UI component. It enables the remote binding of data to the Blazor DataGrid component by connecting to an existing pre-configured API service linked to the MySQL Server database. While the Blazor DataGrid component supports various adaptors to fulfill this requirement, including [Web API](https://blazor.syncfusion.com/documentation/data/adaptors#web-api-adaptor), [OData](https://blazor.syncfusion.com/documentation/data/adaptors#odata-adaptor), [ODataV4](https://blazor.syncfusion.com/documentation/data/adaptors#odatav4-adaptor), [Url](https://blazor.syncfusion.com/documentation/data/adaptors#url-adaptor), and [GraphQL](https://blazor.syncfusion.com/documentation/data/adaptors#graphql-service-binding), the `UrlAdaptor` is particularly useful for the scenarios where a custom API service with unique logic for handling data and CRUD operations is in place. This approach allows for custom handling of data and CRUD operations, and the resultant data returned in the `result` and `count` format for display in the Blazor DataGrid component. * **Using CustomAdaptor** @@ -23,7 +23,7 @@ The [CustomAdaptor](https://blazor.syncfusion.com/documentation/datagrid/custom- ## Binding data from MySQL Server using an API service -This section describes step by step process how to retrieve data from a MySQL server using an API service and bind it to the Blazor DataGrid component. +This section describes step by step process how to retrieve data from a MySQL Server using an API service and bind it to the Blazor DataGrid component. ### Creating an API service @@ -33,7 +33,7 @@ This section describes step by step process how to retrieve data from a MySQL se **3.** Create an API controller (aka, GridController.cs) file under **Controllers** folder that helps to establish data communication with the Blazor DataGrid component. -**4.** In an API controller (aka, GridController), connect to MySQL Server. In the **Get()** method **MySqlConnection** helps to connect the MySQL Server database. Next, using **MySqlCommand** and **MySqlDataAdapter** you can process the desired SQL query string and retrieve data from the database. The **Fill** method of the **DataAdapter** is used to populate the SQL data into a **DataTable** as shown in the following code snippet. +**4.** In an API controller (aka, GridController), connect to MySQL Server. In the **Get()** method **MySqlConnection** helps to connect the MySQL Server database. Next, using **MySqlCommand** and **MySqlDataAdapter** you can process the desired MySQL query string and retrieve data from the database. The **Fill** method of the **DataAdapter** is used to populate the MySQL data into a **DataTable** as shown in the following code snippet. {% tabs %} {% highlight razor tabtitle="GridController.cs"%} @@ -78,7 +78,7 @@ namespace MySqlWebService.Controllers // Using MySqlDataAdapter, process the query string and fill the data into the dataset DataAdapter.Fill(DataTable); sqlConnection.Close(); - //Cast the data fetched from Adapter to List + //Cast the data fetched from MySqlDataAdapter to List var DataSource = (from DataRow Data in DataTable.Rows select new Order() { @@ -177,7 +177,7 @@ The theme stylesheet and script can be accessed from NuGet through [Static Web A **2.** Map the hosted API's URL link `https://localhost:xxxx/api/Grid` to the Blazor DataGrid component in **Index.razor** by using the [Url](https://help.syncfusion.com/cr/blazor/Syncfusion.Blazor.DataManager.html#Syncfusion_Blazor_DataManager_Url) property of [SfDataManager](https://help.syncfusion.com/cr/blazor/Syncfusion.Blazor.Data.SfDataManager.html). To interact with remote data source, provide the endpoint `Url`. -**3.** The `SfDataManager` offers multiple adaptor options to connect with remote database based on an API service. Below is an example of the [UrlAdaptor](https://blazor.syncfusion.com/documentation/data/adaptors#url-adaptor) configuration where an API service are set up to return the resulting data in the `Result` and `Count` format. +**3.** The `SfDataManager` offers multiple adaptor options to connect with remote database based on an API service. Below is an example of the [UrlAdaptor](https://blazor.syncfusion.com/documentation/data/adaptors#url-adaptor) configuration where an API service are set up to return the resulting data in the `result` and `count` format. **4.** The `UrlAdaptor` acts as the base adaptor for interacting with remote data service. Most of the built-in adaptors are derived from the `UrlAdaptor`. @@ -249,28 +249,28 @@ public class GridController : ControllerBase /// /// Returns the data collection as result and count after performing data operations based on request from /// - /// DataManagerRequest contains the information regarding searching, filtering, sorting, aggregates and paging which is handled on the DataGrid component side + /// DataManagerRequest contains the information regarding searching, filtering, sorting, aggregates and paging which is handled on the Blazor DataGrid component side /// The data collection's type is determined by how this method has been implemented. [HttpPost] [Route("api/[controller]")] public object Post([FromBody] DataManagerRequest DataManagerRequest) { IEnumerable DataSource = GetOrderData(); - // Handling Searching in Url Adaptor. + // Handling Searching in UrlAdaptor. if (DataManagerRequest.Search != null && DataManagerRequest.Search.Count > 0) { // Searching DataSource = DataOperations.PerformSearching(DataSource, DataManagerRequest.Search); //Add custom logic here if needed and remove above method } - // Handling Filtering in Url Adaptor. + // Handling Filtering in UrlAdaptor. if (DataManagerRequest.Where != null && DataManagerRequest.Where.Count > 0) { // Filtering DataSource = DataOperations.PerformFiltering(DataSource, DataManagerRequest.Where, DataManagerRequest.Where[0].Operator); //Add custom logic here if needed and remove above method } - // Handling Sorting in Url Adaptor. + // Handling Sorting in UrlAdaptor. if (DataManagerRequest.Sorted != null && DataManagerRequest.Sorted.Count > 0) { // Sorting @@ -278,7 +278,7 @@ public class GridController : ControllerBase //Add custom logic here if needed and remove above method } int count = DataSource.Cast().Count(); - // Handling Aggregation in Url Adaptor. + // Handling Aggregation in UrlAdaptor. IDictionary Aggregates = null; if (DataManagerRequest.Aggregates != null) { @@ -286,7 +286,7 @@ public class GridController : ControllerBase Aggregates = DataUtil.PerformAggregation(DataSource, DataManagerRequest.Aggregates); //Add custom logic here if needed and remove above method } - // Handling paging in Url Adaptor. + // Handling paging in UrlAdaptor. if (DataManagerRequest.Skip != 0) { // Paging @@ -298,8 +298,8 @@ public class GridController : ControllerBase DataSource = DataOperations.PerformTake(DataSource, DataManagerRequest.Take); //Add custom logic here if needed and remove above method } - //Here RequiresCount is passed from the control side itself, where ever the ondemand data fetching is needed then the RequiresCount is set as true in component side itself. - // In the above case we are using Paging so data are loaded in ondemand bases whenever the next page is clicked in DataGrid side. + //Here RequiresCount is passed from the control side itself, where ever the on-demand data fetching is needed then the RequiresCount is set as true in component side itself. + // In the above case we are using paging so data are loaded in on-demand bases whenever the next page is clicked in Blazor DataGrid side. return new { result = DataSource, count = count, aggregates = Aggregates }; } } @@ -312,7 +312,7 @@ When you run the application, the resultant Blazor DataGrid component will look ![Blazor DataGrid component bound with MySQL Server data](../images/blazor-Grid-Ms-SQL-databinding.png) -> * The Syncfusion Blazor DataGrid component provides built-in support for handling various data operations such as **searching**, **sorting**, **filtering**, **aggregate**, **paging** and **grouping** on the server-side. These operations can be handled using methods such as `PerformSearching`, `PerformFiltering`, `PerformSorting`, `PerformAggregation`, `PerformTake` and `PerformSkip` available in the **Syncfusion.Blazor.Data** package. Let's explore how to manage these data operations using the `UrlAdaptor`. +> * The Syncfusion Blazor DataGrid component provides built-in support for handling various data operations such as **searching**, **sorting**, **filtering**, **aggregate** and **paging** on the server-side. These operations can be handled using methods such as `PerformSearching`, `PerformFiltering`, `PerformSorting`, `PerformAggregation`, `PerformTake` and `PerformSkip` available in the **Syncfusion.Blazor.Data** package. Let's explore how to manage these data operations using the `UrlAdaptor`. > * In an API service project, add **Syncfusion.Blazor.Data** by opening the NuGet package manager in Visual Studio (Tools → NuGet Package Manager → Manage NuGet Packages for Solution), search and install it. ### Handling searching operation @@ -326,7 +326,7 @@ To handle searching operation, ensure that your API endpoint supports custom sea public object Post([FromBody] DataManagerRequest DataManagerRequest) { IEnumerable DataSource = GetOrderData(); - // Handling Searching in Url Adaptor. + // Handling Searching in UrlAdaptor. if (DataManagerRequest.Search != null && DataManagerRequest.Search.Count > 0) { // Searching @@ -348,7 +348,7 @@ To handle filtering operation, ensure that your API endpoint supports custom fil public object Post([FromBody] DataManagerRequest DataManagerRequest) { IEnumerable DataSource = GetOrderData(); - // Handling Filtering in Url Adaptor. + // Handling Filtering in UrlAdaptor. if (DataManagerRequest.Where != null && DataManagerRequest.Where.Count > 0) { // Filtering @@ -371,7 +371,7 @@ To handle sorting operation, ensure that your API endpoint supports custom sorti public object Post([FromBody] DataManagerRequest DataManagerRequest) { IEnumerable DataSource = GetOrderData(); - // Handling Sorting in Url Adaptor. + // Handling Sorting in UrlAdaptor. if (DataManagerRequest.Sorted != null && DataManagerRequest.Sorted.Count > 0) { // Sorting @@ -394,7 +394,7 @@ To handle aggregate operation, ensure that your API endpoint supports custom agg { IEnumerable DataSource = GetOrderData(); int count = DataSource.Cast().Count(); - // Handling Aggregation in Url Adaptor. + // Handling Aggregation in UrlAdaptor. IDictionary Aggregates = null; if (DataManagerRequest.Aggregates != null) { @@ -417,7 +417,7 @@ public object Post([FromBody] DataManagerRequest DataManagerRequest) { IEnumerable DataSource = GetOrderData(); int count = DataSource.Cast().Count(); - // Handling Paging in Url Adaptor. + // Handling Paging in UrlAdaptor. if (DataManagerRequest.Skip != 0) { // Paging @@ -433,7 +433,7 @@ public object Post([FromBody] DataManagerRequest DataManagerRequest) } {% endhighlight %} -> For optimal performance, it is recommended to follow this sequence of operations(Searching, Filtering, Sorting, Aggregate, Paging and Grouping ) in the [ReadAsync](https://help.syncfusion.com/cr/blazor/Syncfusion.Blazor.DataAdaptor.html#Syncfusion_Blazor_DataAdaptor_ReadAsync_Syncfusion_Blazor_DataManagerRequest_System_String_) method. +> For optimal performance, it is recommended to follow this sequence of operations(Searching, Filtering, Sorting, Aggregate and Paging ) in the [ReadAsync](https://help.syncfusion.com/cr/blazor/Syncfusion.Blazor.DataAdaptor.html#Syncfusion_Blazor_DataAdaptor_ReadAsync_Syncfusion_Blazor_DataManagerRequest_System_String_) method. ### Handling CRUD operations @@ -457,7 +457,7 @@ In this scenario, the inline edit mode and [Toolbar](https://blazor.syncfusion.c {% endhighlight %} {% endtabs %} -> * Normal editing is the default edit mode for the Blazor DataGrid component. To enable CRUD operations, ensure that the [IsPrimaryKey](https://help.syncfusion.com/cr/blazor/Syncfusion.Blazor.Grids.GridColumn.html#Syncfusion_Blazor_Grids_GridColumn_IsPrimaryKey) property is set to **true** for a specific `GridColumn`, ensuring that its value is unique. +> * Normal/Inline editing is the default edit [Mode](https://help.syncfusion.com/cr/blazor/Syncfusion.Blazor.Grids.GridEditSettings.html#Syncfusion_Blazor_Grids_GridEditSettings_Mode) for the Blazor DataGrid component. To enable CRUD operations, ensure that the [IsPrimaryKey](https://help.syncfusion.com/cr/blazor/Syncfusion.Blazor.Grids.GridColumn.html#Syncfusion_Blazor_Grids_GridColumn_IsPrimaryKey) property is set to **true** for a specific `GridColumn`, ensuring that its value is unique. > * If database has an Autogenerated column, ensure to define [IsIdentity](https://help.syncfusion.com/cr/blazor/Syncfusion.Blazor.Grids.GridColumn.html#Syncfusion_Blazor_Grids_GridColumn_IsIdentity) property of `GridColumn` to disable them during adding or editing operations. **Insert Operation:** @@ -560,7 +560,7 @@ To perform batch operation, define the edit [Mode](https://help.syncfusion.com/c [HttpPost] [Route("api/Grid/Batch")] /// -/// Batchupdate (Insert, Update, Delete) a collection of datas item from the data collection. +/// Batchupdate (Insert, Update, Delete) a collection of data items from the data collection. /// /// The set of information along with details about the CRUD actions to be executed from the database. /// Returns void @@ -628,7 +628,7 @@ When you run the application, the resultant Blazor DataGrid component will look ## Binding data from MySQL Server using CustomAdaptor -This section describes step by step process how to retrieve data from a MySQL server using `CustomAdaptor` and bind it to the Blazor DataGrid component. +This section describes step by step process how to retrieve data from a MySQL Server using `CustomAdaptor` and bind it to the Blazor DataGrid component. **1.** To create a simple Blazor DataGrid component, the procedure is explained in the above-mentioned topic on [Connecting Blazor DataGrid to an API service](#connecting-blazor-datagrid-to-an-api-service) @@ -767,7 +767,7 @@ This section describes step by step process how to retrieve data from a MySQL se @code { /// - /// Implementing custom adaptor by extending the class. + /// Implementing CustomAdaptor by extending the class. /// The Blazor DataGrid component support for custom data binding, which enables the binding and manipulation of data in a personalized way, using user-defined methods. /// public class CustomAdaptor : DataAdaptor @@ -805,7 +805,7 @@ public class OrderData Connection.Open(); // Using MySqlDataAdapter, process the query string and fill the data into the dataset adapter.Fill(data); - //Cast the data fetched from Adapter to List + //Cast the data fetched from MySqlDataAdapter to List Orders = data.Tables[0].AsEnumerable().Select(r => new Order { OrderID = r.Field("OrderID"), @@ -843,7 +843,7 @@ public class CustomAdaptor : DataAdaptor public override async Task ReadAsync(DataManagerRequest DataManagerRequest, string Key = null) { IEnumerable DataSource = await OrderService.GetOrdersAsync(); - // Handling Searching in Custom Adaptor. + // Handling Searching in CustomAdaptor. if (DataManagerRequest.Search != null && DataManagerRequest.Search.Count > 0) { // Searching @@ -870,7 +870,7 @@ public class CustomAdaptor : DataAdaptor public override async Task ReadAsync(DataManagerRequest DataManagerRequest, string Key = null) { IEnumerable DataSource = await OrderService.GetOrdersAsync(); - // Handling Filtering in Custom Adaptor. + // Handling Filtering in CustomAdaptor. if (DataManagerRequest.Where != null && DataManagerRequest.Where.Count > 0) { // Filtering @@ -897,7 +897,7 @@ public class CustomAdaptor : DataAdaptor public override async Task ReadAsync(DataManagerRequest DataManagerRequest, string Key = null) { IEnumerable DataSource = await OrderService.GetOrdersAsync(); - // Handling Sorting in Custom Adaptor. + // Handling Sorting in CustomAdaptor. if (DataManagerRequest.Sorted != null && DataManagerRequest.Sorted.Count > 0) { // Sorting @@ -925,7 +925,7 @@ public class CustomAdaptor : DataAdaptor { IEnumerable DataSource = await OrderService.GetOrdersAsync(); int count = DataSource.Cast().Count(); - // Handling Aggregation in Custom Adaptor. + // Handling Aggregation in CustomAdaptor. IDictionary Aggregates = null; if (DataManagerRequest.Aggregates != null) // Aggregation { @@ -952,7 +952,7 @@ public class CustomAdaptor : DataAdaptor { IEnumerable DataSource = await OrderService.GetOrdersAsync(); int count = DataSource.Cast().Count(); - // Handling paging in Custom Adaptor. + // Handling paging in CustomAdaptor. if (DataManagerRequest.Skip != 0) { // Paging @@ -986,7 +986,7 @@ public class CustomAdaptor : DataAdaptor IEnumerable DataSource = await OrderService.GetOrdersAsync(); int count = DataSource.Cast().Count(); DataResult DataObject = new DataResult(); - // Handling Group operation in Custom Adaptor. + // Handling Group operation in CustomAdaptor. if (DataManagerRequest.Group != null) { IEnumerable ResultData = DataSource.ToList(); @@ -1018,7 +1018,7 @@ public class CustomAdaptor : DataAdaptor IEnumerable DataSource = await OrderService.GetOrdersAsync(); int count = DataSource.Cast().Count(); DataResult DataObject = new DataResult(); - // Handling both Grouping and Aggregation in Custom Adaptor. + // Handling both Grouping and Aggregation in CustomAdaptor. if (DataManagerRequest.Aggregates != null || DataManagerRequest.Group != null) // Aggregation { if (DataManagerRequest.Group != null) @@ -1050,7 +1050,7 @@ public class CustomAdaptor : DataAdaptor To enable editing in the Blazor DataGrid component, utilize the [GridEditSettings](https://help.syncfusion.com/cr/blazor/Syncfusion.Blazor.Grids.GridEditSettings.html) component. The Blazor DataGrid component offers multiple edit modes including the Inline/Normal, Dialog and Batch editing. For more details, refer to the Blazor DataGrid component [editing](https://blazor.syncfusion.com/documentation/datagrid/editing) documentation. -In this scenario, the inline edit mode and [Toolbar](https://blazor.syncfusion.com/documentation/datagrid/tool-bar) property configured to display toolbar items for editing purpose. +In this scenario, the inline edit `Mode` and [Toolbar](https://blazor.syncfusion.com/documentation/datagrid/tool-bar) property configured to display toolbar items for editing purpose. {% highlight razor %} @@ -1066,7 +1066,7 @@ In this scenario, the inline edit mode and [Toolbar](https://blazor.syncfusion.c {% endhighlight %} -> * Normal editing is the default edit mode for the Blazor DataGrid component. To enable CRUD operations, ensure that the [IsPrimaryKey](https://help.syncfusion.com/cr/blazor/Syncfusion.Blazor.Grids.GridColumn.html#Syncfusion_Blazor_Grids_GridColumn_IsPrimaryKey) property is set to **true** for a specific `GridColumn`, ensuring that its value is unique. +> * Inline/Normal editing is the default edit mode for the Blazor DataGrid component. To enable CRUD operations, ensure that the [IsPrimaryKey](https://help.syncfusion.com/cr/blazor/Syncfusion.Blazor.Grids.GridColumn.html#Syncfusion_Blazor_Grids_GridColumn_IsPrimaryKey) property is set to **true** for a specific `GridColumn`, ensuring that its value is unique. > * If database has an Autogenerated column, ensure to define [IsIdentity](https://help.syncfusion.com/cr/blazor/Syncfusion.Blazor.Grids.GridColumn.html#Syncfusion_Blazor_Grids_GridColumn_IsIdentity) property of `GridColumn` to disable them during adding or editing operations. The CRUD operations can be performed and customized on our own by overriding the following CRUD methods of the [DataAdaptor](https://help.syncfusion.com/cr/blazor/Syncfusion.Blazor.DataAdaptor.html) abstract class. @@ -1197,7 +1197,7 @@ To perform the batch operation, override the [BatchUpdate](https://help.syncfusi {% highlight razor %} /// -/// /// Batchupdate (Insert, Update, Delete) a collection of data item from the data collection. +/// /// Batchupdate (Insert, Update, Delete) a collection of data items from the data collection. /// /// The DataManager is a data management component used for performing data operations in application. /// The Changed specifies the collection of record updated in batch mode which needs to be updated from the grid record. From b870cccfa2206d9e12a851d0e7f284becb0bbc9f Mon Sep 17 00:00:00 2001 From: Naveen Date: Tue, 12 Mar 2024 18:00:30 +0530 Subject: [PATCH 5/5] MYSQL-Data-Binding-Documentation(871699) --- .../microsoft-sql-server.md | 163 +++++++----------- .../connecting-to-database/mysql-server.md | 115 ++++-------- 2 files changed, 100 insertions(+), 178 deletions(-) diff --git a/blazor/datagrid/connecting-to-database/microsoft-sql-server.md b/blazor/datagrid/connecting-to-database/microsoft-sql-server.md index 888ffaa273..a4e7f06dbe 100644 --- a/blazor/datagrid/connecting-to-database/microsoft-sql-server.md +++ b/blazor/datagrid/connecting-to-database/microsoft-sql-server.md @@ -15,7 +15,7 @@ Microsoft SQL Server database can be bound to the Blazor DataGrid component in d * **Using UrlAdaptor** -The [UrlAdaptor](https://blazor.syncfusion.com/documentation/data/adaptors#url-adaptor) serves as the base adaptor for facilitating communication between remote data services and an UI component. It enables the remote binding of data to the Blazor DataGrid component by connecting to an existing pre-configured API service linked to the Microsoft SQL Server database. While the Blazor DataGrid component supports various adaptors to fulfill this requirement, including [Web API](https://blazor.syncfusion.com/documentation/data/adaptors#web-api-adaptor), [OData](https://blazor.syncfusion.com/documentation/data/adaptors#odata-adaptor), [ODataV4](https://blazor.syncfusion.com/documentation/data/adaptors#odatav4-adaptor), [Url](https://blazor.syncfusion.com/documentation/data/adaptors#url-adaptor), and [GraphQL](https://blazor.syncfusion.com/documentation/data/adaptors#graphql-service-binding), the `UrlAdaptor` is particularly useful for the scenarios where a custom API service with unique logic for handling data and CRUD operations is in place. This approach allows for custom handling of data and CRUD operations, and the resultant data returned in the `Result` and `Count` format for display in the Blazor DataGrid component. +The [UrlAdaptor](https://blazor.syncfusion.com/documentation/data/adaptors#url-adaptor) serves as the base adaptor for facilitating communication between remote data services and an UI component. It enables the remote binding of data to the Blazor DataGrid component by connecting to an existing pre-configured API service linked to the Microsoft SQL Server database. While the Blazor DataGrid component supports various adaptors to fulfill this requirement, including [Web API](https://blazor.syncfusion.com/documentation/data/adaptors#web-api-adaptor), [OData](https://blazor.syncfusion.com/documentation/data/adaptors#odata-adaptor), [ODataV4](https://blazor.syncfusion.com/documentation/data/adaptors#odatav4-adaptor), [Url](https://blazor.syncfusion.com/documentation/data/adaptors#url-adaptor), and [GraphQL](https://blazor.syncfusion.com/documentation/data/adaptors#graphql-service-binding), the `UrlAdaptor` is particularly useful for the scenarios where a custom API service with unique logic for handling data and CRUD operations is in place. This approach allows for custom handling of data and CRUD operations, and the resultant data returned in the `result` and `count` format for display in the Blazor DataGrid component. * **Using CustomAdaptor** @@ -23,7 +23,7 @@ The [CustomAdaptor](https://blazor.syncfusion.com/documentation/datagrid/custom- ## Binding data from Microsoft SQL Server using an API service -This section describes step by step process how to retrieve data from a Microsoft SQL server using an API service and bind it to the Blazor DataGrid component. +This section describes step by step process how to retrieve data from a Microsoft SQL Server using an API service and bind it to the Blazor DataGrid component. ### Creating an API service @@ -77,7 +77,7 @@ namespace MyWebService.Controllers // Using SqlDataAdapter, process the query string and fill the data into the dataset DataAdapter.Fill(DataTable); sqlConnection.Close(); - //Cast the data fetched from Adapter to List + //Cast the data fetched from SqlDataAdapter to List var DataSource = (from DataRow Data in DataTable.Rows select new Order() { @@ -176,7 +176,7 @@ The theme stylesheet and script can be accessed from NuGet through [Static Web A **2.** Map the hosted API's URL link `https://localhost:xxxx/api/Grid` to the Blazor DataGrid component in **Index.razor** by using the [Url](https://help.syncfusion.com/cr/blazor/Syncfusion.Blazor.DataManager.html#Syncfusion_Blazor_DataManager_Url) property of [SfDataManager](https://help.syncfusion.com/cr/blazor/Syncfusion.Blazor.Data.SfDataManager.html). To interact with remote data source, provide the endpoint `Url`. -**3.** The `SfDataManager` offers multiple adaptor options to connect with remote database based on an API service. Below is an example of the [UrlAdaptor](https://blazor.syncfusion.com/documentation/data/adaptors#url-adaptor) configuration where an API service are set up to return the resulting data in the `Result` and `Count` format. +**3.** The `SfDataManager` offers multiple adaptor options to connect with remote database based on an API service. Below is an example of the [UrlAdaptor](https://blazor.syncfusion.com/documentation/data/adaptors#url-adaptor) configuration where an API service are set up to return the resulting data in the `result` and `count` format. **4.** The `UrlAdaptor` acts as the base adaptor for interacting with remote data service. Most of the built-in adaptors are derived from the `UrlAdaptor`. @@ -256,51 +256,8 @@ The theme stylesheet and script can be accessed from NuGet through [Static Web A public object Post([FromBody] DataManagerRequest DataManagerRequest) { IEnumerable DataSource = GetOrderData(); - // Handling Searching in Url Adaptor. - if (DataManagerRequest.Search != null && DataManagerRequest.Search.Count > 0) - { - // Searching - DataSource = DataOperations.PerformSearching(DataSource, DataManagerRequest.Search); - //Add custom logic here if needed and remove above method - } - // Handling Filtering in Url Adaptor. - if (DataManagerRequest.Where != null && DataManagerRequest.Where.Count > 0) - { - // Filtering - DataSource = DataOperations.PerformFiltering(DataSource, DataManagerRequest.Where, DataManagerRequest.Where[0].Operator); - //Add custom logic here if needed and remove above method - } - // Handling Sorting in Url Adaptor. - if (DataManagerRequest.Sorted != null && DataManagerRequest.Sorted.Count > 0) - { - // Sorting - DataSource = DataOperations.PerformSorting(DataSource, DataManagerRequest.Sorted); - //Add custom logic here if needed and remove above method - } - int count = DataSource.Cast().Count(); - // Handling Aggregation in Url Adaptor. - IDictionary Aggregates = null; - if (DataManagerRequest.Aggregates != null) - { - // Aggregation - Aggregates = DataUtil.PerformAggregation(DataSource, DataManagerRequest.Aggregates); - //Add custom logic here if needed and remove above method - } - // Handling Paging in Url Adaptor. - if (DataManagerRequest.Skip != 0) - { - // Paging - DataSource = DataOperations.PerformSkip(DataSource, DataManagerRequest.Skip); - //Add custom logic here if needed and remove above method - } - if (DataManagerRequest.Take != 0) - { - DataSource = DataOperations.PerformTake(DataSource, DataManagerRequest.Take); - //Add custom logic here if needed and remove above method - } - //Here RequiresCount is passed from the control side itself, where ever the ondemand data fetching is needed then the RequiresCount is set as true in component side itself. - // In the above case we are using Paging so data are loaded in ondemand bases whenever the next page is clicked in DataGrid side. - return new { result = DataSource, count = count, aggregates = Aggregates }; + int TotalRecordsCount = DataSource.Cast().Count(); + return new { result = DataSource, count = TotalRecordsCount }; } } {% endhighlight %} @@ -312,7 +269,7 @@ When you run the application, the resultant Blazor DataGrid component will look ![Blazor DataGrid component bound with Microsoft SQL Server data](../images/blazor-Grid-Ms-SQL-databinding.png) -> * The Syncfusion Blazor DataGrid component provides built-in support for handling various data operations such as **searching**, **sorting**, **filtering**, **aggregate**, **paging** and **grouping** on the server-side. These operations can be handled using methods such as `PerformSearching`, `PerformFiltering`, `PerformSorting`, `PerformAggregation`, `PerformTake` and `PerformSkip` available in the **Syncfusion.Blazor.Data** package. Let's explore how to manage these data operations using the `UrlAdaptor`. +> * The Syncfusion Blazor DataGrid component provides built-in support for handling various data operations such as **searching**, **sorting**, **filtering**, **aggregate** and **paging** on the server-side. These operations can be handled using methods such as `PerformSearching`, `PerformFiltering`, `PerformSorting`, `PerformAggregation`, `PerformTake` and `PerformSkip` available in the **Syncfusion.Blazor.Data** package. Let's explore how to manage these data operations using the `UrlAdaptor`. > * In an API service project, add **Syncfusion.Blazor.Data** by opening the NuGet package manager in Visual Studio (Tools → NuGet Package Manager → Manage NuGet Packages for Solution), search and install it. ### Handling searching operation @@ -326,15 +283,15 @@ To handle searching operation, ensure that your API endpoint supports custom sea public object Post([FromBody] DataManagerRequest DataManagerRequest) { IEnumerable DataSource = GetOrderData(); - // Handling Searching in Url Adaptor. + // Handling Searching in UrlAdaptor. if (DataManagerRequest.Search != null && DataManagerRequest.Search.Count > 0) { // Searching DataSource = DataOperations.PerformSearching(DataSource, DataManagerRequest.Search); //Add custom logic here if needed and remove above method } - int count = DataSource.Cast().Count(); - return new { result = DataSource, count = count }; + int TotalRecordsCount = DataSource.Cast().Count(); + return new { result = DataSource, count = TotalRecordsCount }; } {% endhighlight %} @@ -348,15 +305,15 @@ To handle filtering operation, ensure that your API endpoint supports custom fil public object Post([FromBody] DataManagerRequest DataManagerRequest) { IEnumerable DataSource = GetOrderData(); - // Handling Filtering in Url Adaptor. + // Handling Filtering in UrlAdaptor. if (DataManagerRequest.Where != null && DataManagerRequest.Where.Count > 0) { // Filtering DataSource = DataOperations.PerformFiltering(DataSource, DataManagerRequest.Where, DataManagerRequest.Where[0].Operator); //Add custom logic here if needed and remove above method } - int count = DataSource.Cast().Count(); - return new { result = DataSource, count = count }; + int TotalRecordsCount = DataSource.Cast().Count(); + return new { result = DataSource, count = TotalRecordsCount }; } {% endhighlight %} @@ -371,15 +328,15 @@ To handle sorting operation, ensure that your API endpoint supports custom sorti public object Post([FromBody] DataManagerRequest DataManagerRequest) { IEnumerable DataSource = GetOrderData(); - // Handling Sorting in Url Adaptor. + // Handling Sorting in UrlAdaptor. if (DataManagerRequest.Sorted != null && DataManagerRequest.Sorted.Count > 0) { // Sorting DataSource = DataOperations.PerformSorting(DataSource, DataManagerRequest.Sorted); //Add custom logic here if needed and remove above method } - int count = DataSource.Cast().Count(); - return new { result = DataSource, count = count }; + int TotalRecordsCount = DataSource.Cast().Count(); + return new { result = DataSource, count = TotalRecordsCount }; } {% endhighlight %} @@ -393,8 +350,8 @@ To handle aggregate operation, ensure that your API endpoint supports custom agg public object Post([FromBody] DataManagerRequest DataManagerRequest) { IEnumerable DataSource = GetOrderData(); - int count = DataSource.Cast().Count(); - // Handling Aggregation in Url Adaptor. + int TotalRecordsCount = DataSource.Cast().Count(); + // Handling Aggregation in UrlAdaptor. IDictionary Aggregates = null; if (DataManagerRequest.Aggregates != null) { @@ -402,10 +359,12 @@ To handle aggregate operation, ensure that your API endpoint supports custom agg Aggregates = DataUtil.PerformAggregation(DataSource, DataManagerRequest.Aggregates); //Add custom logic here if needed and remove above method } - return new { result = DataSource, count = count, aggregates = Aggregates }; + return new { result = DataSource, count = TotalRecordsCount, aggregates = Aggregates }; } {% endhighlight %} +> The server-side management of the `PerformAggregation` method is necessary only for the [Footer Template](https://blazor.syncfusion.com/documentation/datagrid/footer-aggregate) aggregation. There is no need for explicit handling of the Aggregate operation for the [Group Footer template](https://blazor.syncfusion.com/documentation/datagrid/group-and-caption-aggregate#group-footer-aggregates) and [Group Caption template](https://blazor.syncfusion.com/documentation/datagrid/group-and-caption-aggregate#group-caption-aggregates). + ### Handling paging operation To handle paging operation, ensure that your API endpoint supports custom paging criteria. Implement the paging logic on the server-side using the [PerformTake](https://help.syncfusion.com/cr/blazor/Syncfusion.Blazor.DataOperations.html#Syncfusion_Blazor_DataOperations_PerformTake_System_Collections_IEnumerable_System_Int32_) and [PerformSkip](https://help.syncfusion.com/cr/blazor/Syncfusion.Blazor.DataOperations.html#Syncfusion_Blazor_DataOperations_PerformSkip__1_System_Collections_Generic_IEnumerable___0__System_Int32_) method from the [DataOperations](https://help.syncfusion.com/cr/blazor/Syncfusion.Blazor.DataOperations.html) class. This allows the custom data source to undergo paging based on the criteria specified in the incoming [DataManagerRequest](https://help.syncfusion.com/cr/blazor/Syncfusion.Blazor.DataManagerRequest.html) object. @@ -416,8 +375,8 @@ To handle paging operation, ensure that your API endpoint supports custom paging public object Post([FromBody] DataManagerRequest DataManagerRequest) { IEnumerable DataSource = GetOrderData(); - int count = DataSource.Cast().Count(); - // Handling Paging in Url Adaptor. + int TotalRecordsCount = DataSource.Cast().Count(); + // Handling Paging in UrlAdaptor. if (DataManagerRequest.Skip != 0) { // Paging @@ -429,17 +388,17 @@ public object Post([FromBody] DataManagerRequest DataManagerRequest) DataSource = DataOperations.PerformTake(DataSource, DataManagerRequest.Take); //Add custom logic here if needed and remove above method } - return new { result = DataSource, count = count }; + return new { result = DataSource, count = TotalRecordsCount }; } {% endhighlight %} -> For optimal performance, it is recommended to follow this sequence of operations(Searching, Filtering, Sorting, Aggregate, Paging and Grouping ) in the [ReadAsync](https://help.syncfusion.com/cr/blazor/Syncfusion.Blazor.DataAdaptor.html#Syncfusion_Blazor_DataAdaptor_ReadAsync_Syncfusion_Blazor_DataManagerRequest_System_String_) method. +> For optimal performance, it is recommended to follow this sequence of operations(Searching, Filtering, Sorting, Aggregate and Paging) in the [ReadAsync](https://help.syncfusion.com/cr/blazor/Syncfusion.Blazor.DataAdaptor.html#Syncfusion_Blazor_DataAdaptor_ReadAsync_Syncfusion_Blazor_DataManagerRequest_System_String_) method. ### Handling CRUD operations To enable editing in this Blazor DataGrid component, utilize the [GridEditSettings](https://help.syncfusion.com/cr/blazor/Syncfusion.Blazor.Grids.GridEditSettings.html) component. The Blazor DataGrid offers multiple edit modes including the [Inline/Normal](https://blazor.syncfusion.com/documentation/datagrid/in-line-editing), [Dialog](https://blazor.syncfusion.com/documentation/datagrid/dialog-editing), and [Batch](https://blazor.syncfusion.com/documentation/datagrid/batch-editing) editing. For more details, refer to the Blazor DataGrid component [editing](https://blazor.syncfusion.com/documentation/datagrid/editing) documentation. -In this scenario, the inline edit mode and [Toolbar](https://blazor.syncfusion.com/documentation/datagrid/tool-bar) property are configured to display toolbar items for editing purposes. +In this scenario, the inline edit `Mode` and [Toolbar](https://blazor.syncfusion.com/documentation/datagrid/tool-bar) property are configured to display toolbar items for editing purposes. {% tabs %} {% highlight razor %} @@ -457,7 +416,7 @@ In this scenario, the inline edit mode and [Toolbar](https://blazor.syncfusion.c {% endhighlight %} {% endtabs %} -> * Normal editing is the default edit mode for the Blazor DataGrid component. To enable CRUD operations, ensure that the [IsPrimaryKey](https://help.syncfusion.com/cr/blazor/Syncfusion.Blazor.Grids.GridColumn.html#Syncfusion_Blazor_Grids_GridColumn_IsPrimaryKey) property is set to **true** for a specific `GridColumn`, ensuring that its value is unique. +> * Normal/Inline editing is the default edit [Mode](https://help.syncfusion.com/cr/blazor/Syncfusion.Blazor.Grids.GridEditSettings.html#Syncfusion_Blazor_Grids_GridEditSettings_Mode) for the Blazor DataGrid component. To enable CRUD operations, ensure that the [IsPrimaryKey](https://help.syncfusion.com/cr/blazor/Syncfusion.Blazor.Grids.GridColumn.html#Syncfusion_Blazor_Grids_GridColumn_IsPrimaryKey) property is set to **true** for a specific `GridColumn`, ensuring that its value is unique. > * If database has an Autogenerated column, ensure to define [IsIdentity](https://help.syncfusion.com/cr/blazor/Syncfusion.Blazor.Grids.GridColumn.html#Syncfusion_Blazor_Grids_GridColumn_IsIdentity) property of `GridColumn` to disable them during adding or editing operations. **Insert Operation:** @@ -560,7 +519,7 @@ To perform batch operation, define the edit [Mode](https://help.syncfusion.com/c [HttpPost] [Route("api/Grid/Batch")] /// -/// Batchupdate (Insert, Update, Delete) a collection of datas item from the data collection. +/// Batchupdate (Insert, Update, Delete) a collection of data items from the data collection. /// /// The set of information along with details about the CRUD actions to be executed from the database. /// Returns void @@ -628,7 +587,7 @@ When you run the application, the resultant Blazor DataGrid component will look ## Binding data from Microsoft SQL Server using CustomAdaptor -This section describes step by step process how to retrieve data from a Microsoft SQL server using `CustomAdaptor` and bind it to the Blazor DataGrid component. +This section describes step by step process how to retrieve data from a Microsoft SQL Server using `CustomAdaptor` and bind it to the Blazor DataGrid component. **1.** To create a simple Blazor DataGrid component, the procedure is explained in the above-mentioned topic on [Connecting Blazor DataGrid to an API service](#connecting-blazor-datagrid-to-an-api-service) @@ -766,7 +725,7 @@ This section describes step by step process how to retrieve data from a Microsof @code { /// - /// Implementing custom adaptor by extending the class. + /// Implementing CustomAdaptor by extending the class. /// The Blazor DataGrid component support for custom data binding, which enables the binding and manipulation of data in a personalized way, using user-defined methods. /// public class CustomAdaptor : DataAdaptor @@ -781,8 +740,8 @@ This section describes step by step process how to retrieve data from a Microsof public override async Task ReadAsync(DataManagerRequest DataManagerRequest, string Key = null) { IEnumerable DataSource = await OrderService.GetOrdersAsync(); - int count = DataSource.Cast().Count(); - return DataManagerRequest.RequiresCounts ? new DataResult() { Result = DataSource, Count = count } : (object)DataSource; + int TotalRecordsCount = DataSource.Cast().Count(); + return DataManagerRequest.RequiresCounts ? new DataResult() { Result = DataSource, Count = TotalRecordsCount } : (object)DataSource; } } } @@ -804,7 +763,7 @@ public class OrderData Connection.Open(); // Using SqlDataAdapter, process the query string and fill the data into the dataset Adapter.Fill(Data); - //Cast the data fetched from Adapter to List + //Cast the data fetched from SqlDataAdapter to List Orders = Data.Tables[0].AsEnumerable().Select(r => new Order { OrderID = r.Field("OrderID"), @@ -842,15 +801,15 @@ public class CustomAdaptor : DataAdaptor public override async Task ReadAsync(DataManagerRequest DataManagerRequest, string Key = null) { IEnumerable DataSource = await OrderService.GetOrdersAsync(); - // Handling Searching in Custom Adaptor. + // Handling Searching in CustomAdaptor. if (DataManagerRequest.Search != null && DataManagerRequest.Search.Count > 0) { // Searching DataSource = DataOperations.PerformSearching(DataSource, DataManagerRequest.Search); //Add custom logic here if needed and remove above method } - int count = DataSource.Cast().Count(); - return DataManagerRequest.RequiresCounts ? new DataResult() { Result = DataSource, Count = count } : (object)DataSource; + int TotalRecordsCount = DataSource.Cast().Count(); + return DataManagerRequest.RequiresCounts ? new DataResult() { Result = DataSource, Count = TotalRecordsCount } : (object)DataSource; } } {% endhighlight %} @@ -869,15 +828,15 @@ public class CustomAdaptor : DataAdaptor public override async Task ReadAsync(DataManagerRequest DataManagerRequest, string Key = null) { IEnumerable DataSource = await OrderService.GetOrdersAsync(); - // Handling Filtering in Custom Adaptor. + // Handling Filtering in CustomAdaptor. if (DataManagerRequest.Where != null && DataManagerRequest.Where.Count > 0) { // Filtering DataSource = DataOperations.PerformFiltering(DataSource, DataManagerRequest.Where, DataManagerRequest.Where[0].Operator); //Add custom logic here if needed and remove above method } - int count = DataSource.Cast().Count(); - return DataManagerRequest.RequiresCounts ? new DataResult() { Result = DataSource, Count = count } : (object)DataSource; + int TotalRecordsCount = DataSource.Cast().Count(); + return DataManagerRequest.RequiresCounts ? new DataResult() { Result = DataSource, Count = TotalRecordsCount } : (object)DataSource; } } {% endhighlight %} @@ -896,15 +855,15 @@ public class CustomAdaptor : DataAdaptor public override async Task ReadAsync(DataManagerRequest DataManagerRequest, string Key = null) { IEnumerable DataSource = await OrderService.GetOrdersAsync(); - // Handling Sorting in Custom Adaptor. + // Handling Sorting in CustomAdaptor. if (DataManagerRequest.Sorted != null && DataManagerRequest.Sorted.Count > 0) { // Sorting DataSource = DataOperations.PerformSorting(DataSource, DataManagerRequest.Sorted); //Add custom logic here if needed and remove above method } - int count = DataSource.Cast().Count(); - return DataManagerRequest.RequiresCounts ? new DataResult() { Result = DataSource, Count = count } : (object)DataSource; + int TotalRecordsCount = DataSource.Cast().Count(); + return DataManagerRequest.RequiresCounts ? new DataResult() { Result = DataSource, Count = TotalRecordsCount } : (object)DataSource; } } {% endhighlight %} @@ -923,19 +882,21 @@ public class CustomAdaptor : DataAdaptor public override async Task ReadAsync(DataManagerRequest DataManagerRequest, string Key = null) { IEnumerable DataSource = await OrderService.GetOrdersAsync(); - int count = DataSource.Cast().Count(); - // Handling Aggregation in Custom Adaptor. + int TotalRecordsCount = DataSource.Cast().Count(); + // Handling Aggregation in CustomAdaptor. IDictionary Aggregates = null; if (DataManagerRequest.Aggregates != null) // Aggregation { Aggregates = DataUtil.PerformAggregation(DataSource, DataManagerRequest.Aggregates); //Add custom logic here if needed and remove above method } - return DataManagerRequest.RequiresCounts ? new DataResult() { Result = DataSource, Count = count, Aggregates = Aggregates } : (object)DataSource; + return DataManagerRequest.RequiresCounts ? new DataResult() { Result = DataSource, Count = TotalRecordsCount, Aggregates = Aggregates } : (object)DataSource; } } {% endhighlight %} +> The server-side management of the `PerformAggregation` method is necessary only for the [Footer Template](https://blazor.syncfusion.com/documentation/datagrid/footer-aggregate) aggregation. There is no need for explicit handling of the Aggregate operation for the [Group Footer template](https://blazor.syncfusion.com/documentation/datagrid/group-and-caption-aggregate#group-footer-aggregates) and [Group Caption template](https://blazor.syncfusion.com/documentation/datagrid/group-and-caption-aggregate#group-caption-aggregates). + ### Handling paging operation When employing the `CustomAdaptor`, handling paging operation involves overriding the [Read](https://help.syncfusion.com/cr/blazor/Syncfusion.Blazor.DataAdaptor.html#Syncfusion_Blazor_DataAdaptor_Read_Syncfusion_Blazor_DataManagerRequest_System_String_) or [ReadAsync](https://help.syncfusion.com/cr/blazor/Syncfusion.Blazor.DataAdaptor.html#Syncfusion_Blazor_DataAdaptor_ReadAsync_Syncfusion_Blazor_DataManagerRequest_System_String_) method of the [DataAdaptor](https://help.syncfusion.com/cr/blazor/Syncfusion.Blazor.DataAdaptor.html) abstract class. @@ -950,8 +911,8 @@ public class CustomAdaptor : DataAdaptor public override async Task ReadAsync(DataManagerRequest DataManagerRequest, string Key = null) { IEnumerable DataSource = await OrderService.GetOrdersAsync(); - int count = DataSource.Cast().Count(); - // Handling paging in Custom Adaptor. + int TotalRecordsCount = DataSource.Cast().Count(); + // Handling paging in CustomAdaptor. if (DataManagerRequest.Skip != 0) { // Paging @@ -964,7 +925,7 @@ public class CustomAdaptor : DataAdaptor DataSource = DataOperations.PerformTake(DataSource, DataManagerRequest.Take); //Add custom logic here if needed and remove above method } - return DataManagerRequest.RequiresCounts ? new DataResult() { Result = DataSource, Count = count } : (object)DataSource; + return DataManagerRequest.RequiresCounts ? new DataResult() { Result = DataSource, Count = TotalRecordsCount } : (object)DataSource; } } {% endhighlight %} @@ -973,7 +934,7 @@ public class CustomAdaptor : DataAdaptor When employing `CustomAdaptor`, the grouping operation must be managed within the [Read](https://help.syncfusion.com/cr/blazor/Syncfusion.Blazor.DataAdaptor.html#Syncfusion_Blazor_DataAdaptor_Read_Syncfusion_Blazor_DataManagerRequest_System_String_) or [ReadAsync](https://help.syncfusion.com/cr/blazor/Syncfusion.Blazor.DataAdaptor.html#Syncfusion_Blazor_DataAdaptor_ReadAsync_Syncfusion_Blazor_DataManagerRequest_System_String_) method of the `CustomAdaptor`. -The provided sample code illustrated how to implement the grouping operation within `CustomAdaptor`, +In the code example below, grouping a custom data source can be achieved by utilizing the [Group](https://help.syncfusion.com/cr/blazor/Syncfusion.Blazor.Data.DataUtil.html#Syncfusion_Blazor_Data_DataUtil_Group__1_System_Collections_IEnumerable_System_String_System_Collections_Generic_List_Syncfusion_Blazor_Data_Aggregate__System_Int32_System_Collections_Generic_IDictionary_System_String_System_String__System_Boolean_System_Boolean_) method from the [DataUtil](https://help.syncfusion.com/cr/blazor/Syncfusion.Blazor.Data.DataUtil.html) class. Alternatively, you can use your own method for grouping operation and bind the resulting data to the Blazor DataGrid component. {% highlight razor %} public class CustomAdaptor : DataAdaptor @@ -983,9 +944,9 @@ public class CustomAdaptor : DataAdaptor public override async Task ReadAsync(DataManagerRequest DataManagerRequest, string Key = null) { IEnumerable DataSource = await OrderService.GetOrdersAsync(); - int count = DataSource.Cast().Count(); + int TotalRecordsCount = DataSource.Cast().Count(); DataResult DataObject = new DataResult(); - // Handling Group operation in Custom Adaptor. + // Handling Group operation in CustomAdaptor. if (DataManagerRequest.Group != null) { IEnumerable ResultData = DataSource.ToList(); @@ -996,10 +957,10 @@ public class CustomAdaptor : DataAdaptor //Add custom logic here if needed and remove above method } DataObject.Result = ResultData; - DataObject.Count = count; + DataObject.Count = TotalRecordsCount; return DataManagerRequest.RequiresCounts ? DataObject : (object)ResultData; } - return DataManagerRequest.RequiresCounts ? new DataResult() { Result = DataSource, Count = count } : (object)DataSource; + return DataManagerRequest.RequiresCounts ? new DataResult() { Result = DataSource, Count = TotalRecordsCount } : (object)DataSource; } } {% endhighlight %} @@ -1015,9 +976,9 @@ public class CustomAdaptor : DataAdaptor public override async Task ReadAsync(DataManagerRequest DataManagerRequest, string Key = null) { IEnumerable DataSource = await OrderService.GetOrdersAsync(); - int count = DataSource.Cast().Count(); + int TotalRecordsCount = DataSource.Cast().Count(); DataResult DataObject = new DataResult(); - // Handling both Grouping and Aggregation in Custom Adaptor. + // Handling both Grouping and Aggregation in CustomAdaptor. if (DataManagerRequest.Aggregates != null || DataManagerRequest.Group != null) // Aggregation { if (DataManagerRequest.Group != null) @@ -1035,12 +996,12 @@ public class CustomAdaptor : DataAdaptor { DataObject.Result = DataSource; } - DataObject.Count = count; + DataObject.Count = TotalRecordsCount; DataObject.Aggregates = DataUtil.PerformAggregation(DataSource, DataManagerRequest.Aggregates); return DataManagerRequest.RequiresCounts ? DataObject : (object)DataSource; } - return DataManagerRequest.RequiresCounts ? new DataResult() { Result = DataSource, Count = count } : (object)DataSource; + return DataManagerRequest.RequiresCounts ? new DataResult() { Result = DataSource, Count = TotalRecordsCount } : (object)DataSource; } } ``` @@ -1049,7 +1010,7 @@ public class CustomAdaptor : DataAdaptor To enable editing in the Blazor DataGrid component, utilize the [GridEditSettings](https://help.syncfusion.com/cr/blazor/Syncfusion.Blazor.Grids.GridEditSettings.html) component. The Blazor DataGrid component offers multiple edit modes including the Inline/Normal, Dialog and Batch editing. For more details, refer to the Blazor DataGrid component [editing](https://blazor.syncfusion.com/documentation/datagrid/editing) documentation. -In this scenario, the inline edit mode and [Toolbar](https://blazor.syncfusion.com/documentation/datagrid/tool-bar) property configured to display toolbar items for editing purpose. +In this scenario, the inline edit `Mode` and [Toolbar](https://blazor.syncfusion.com/documentation/datagrid/tool-bar) property configured to display toolbar items for editing purpose. {% highlight razor %} @@ -1065,7 +1026,7 @@ In this scenario, the inline edit mode and [Toolbar](https://blazor.syncfusion.c {% endhighlight %} -> * Normal editing is the default edit mode for the Blazor DataGrid component. To enable CRUD operations, ensure that the [IsPrimaryKey](https://help.syncfusion.com/cr/blazor/Syncfusion.Blazor.Grids.GridColumn.html#Syncfusion_Blazor_Grids_GridColumn_IsPrimaryKey) property is set to **true** for a specific `GridColumn`, ensuring that its value is unique. +> * Normal/Inline editing is the default edit [Mode](https://help.syncfusion.com/cr/blazor/Syncfusion.Blazor.Grids.GridEditSettings.html#Syncfusion_Blazor_Grids_GridEditSettings_Mode) for the Blazor DataGrid component. To enable CRUD operations, ensure that the [IsPrimaryKey](https://help.syncfusion.com/cr/blazor/Syncfusion.Blazor.Grids.GridColumn.html#Syncfusion_Blazor_Grids_GridColumn_IsPrimaryKey) property is set to **true** for a specific `GridColumn`, ensuring that its value is unique. > * If database has an Autogenerated column, ensure to define [IsIdentity](https://help.syncfusion.com/cr/blazor/Syncfusion.Blazor.Grids.GridColumn.html#Syncfusion_Blazor_Grids_GridColumn_IsIdentity) property of `GridColumn` to disable them during adding or editing operations. The CRUD operations can be performed and customized on our own by overriding the following CRUD methods of the [DataAdaptor](https://help.syncfusion.com/cr/blazor/Syncfusion.Blazor.DataAdaptor.html) abstract class. @@ -1196,7 +1157,7 @@ To perform the batch operation, override the [BatchUpdate](https://help.syncfusi {% highlight razor %} /// -/// /// Batchupdate (Insert, Update, Delete) a collection of data item from the data collection. +/// /// Batchupdate (Insert, Update, Delete) a collection of data items from the data collection. /// /// The DataManager is a data management component used for performing data operations in application. /// The Changed specifies the collection of record updated in batch mode which needs to be updated from the grid record. diff --git a/blazor/datagrid/connecting-to-database/mysql-server.md b/blazor/datagrid/connecting-to-database/mysql-server.md index 0f20acfa6c..7a2ab7a5ec 100644 --- a/blazor/datagrid/connecting-to-database/mysql-server.md +++ b/blazor/datagrid/connecting-to-database/mysql-server.md @@ -45,7 +45,7 @@ using Syncfusion.Blazor.Data; using System.ComponentModel.DataAnnotations; using Newtonsoft.Json; -namespace MySqlWebService.Controllers +namespace MyWebService.Controllers { [ApiController] public class GridController : ControllerBase @@ -256,51 +256,8 @@ public class GridController : ControllerBase public object Post([FromBody] DataManagerRequest DataManagerRequest) { IEnumerable DataSource = GetOrderData(); - // Handling Searching in UrlAdaptor. - if (DataManagerRequest.Search != null && DataManagerRequest.Search.Count > 0) - { - // Searching - DataSource = DataOperations.PerformSearching(DataSource, DataManagerRequest.Search); - //Add custom logic here if needed and remove above method - } - // Handling Filtering in UrlAdaptor. - if (DataManagerRequest.Where != null && DataManagerRequest.Where.Count > 0) - { - // Filtering - DataSource = DataOperations.PerformFiltering(DataSource, DataManagerRequest.Where, DataManagerRequest.Where[0].Operator); - //Add custom logic here if needed and remove above method - } - // Handling Sorting in UrlAdaptor. - if (DataManagerRequest.Sorted != null && DataManagerRequest.Sorted.Count > 0) - { - // Sorting - DataSource = DataOperations.PerformSorting(DataSource, DataManagerRequest.Sorted); - //Add custom logic here if needed and remove above method - } - int count = DataSource.Cast().Count(); - // Handling Aggregation in UrlAdaptor. - IDictionary Aggregates = null; - if (DataManagerRequest.Aggregates != null) - { - //Aggregation - Aggregates = DataUtil.PerformAggregation(DataSource, DataManagerRequest.Aggregates); - //Add custom logic here if needed and remove above method - } - // Handling paging in UrlAdaptor. - if (DataManagerRequest.Skip != 0) - { - // Paging - DataSource = DataOperations.PerformSkip(DataSource, DataManagerRequest.Skip); - //Add custom logic here if needed and remove above method - } - if (DataManagerRequest.Take != 0) - { - DataSource = DataOperations.PerformTake(DataSource, DataManagerRequest.Take); - //Add custom logic here if needed and remove above method - } - //Here RequiresCount is passed from the control side itself, where ever the on-demand data fetching is needed then the RequiresCount is set as true in component side itself. - // In the above case we are using paging so data are loaded in on-demand bases whenever the next page is clicked in Blazor DataGrid side. - return new { result = DataSource, count = count, aggregates = Aggregates }; + int TotalRecordsCount = DataSource.Cast().Count(); + return new { result = DataSource, count = TotalRecordsCount}; } } {% endhighlight %} @@ -333,8 +290,8 @@ public object Post([FromBody] DataManagerRequest DataManagerRequest) DataSource = DataOperations.PerformSearching(DataSource, DataManagerRequest.Search); //Add custom logic here if needed and remove above method } - int count = DataSource.Cast().Count(); - return new { result = DataSource, count = count }; + int TotalRecordsCount = DataSource.Cast().Count(); + return new { result = DataSource, count = TotalRecordsCount }; } {% endhighlight %} @@ -355,8 +312,8 @@ public object Post([FromBody] DataManagerRequest DataManagerRequest) DataSource = DataOperations.PerformFiltering(DataSource, DataManagerRequest.Where, DataManagerRequest.Where[0].Operator); //Add custom logic here if needed and remove above method } - int count = DataSource.Cast().Count(); - return new { result = DataSource, count = count }; + int TotalRecordsCount = DataSource.Cast().Count(); + return new { result = DataSource, count = TotalRecordsCount }; } {% endhighlight %} @@ -378,8 +335,8 @@ public object Post([FromBody] DataManagerRequest DataManagerRequest) DataSource = DataOperations.PerformSorting(DataSource, DataManagerRequest.Sorted); //Add custom logic here if needed and remove above method } - int count = DataSource.Cast().Count(); - return new { result = DataSource, count = count }; + int TotalRecordsCount = DataSource.Cast().Count(); + return new { result = DataSource, count = TotalRecordsCount }; } {% endhighlight %} @@ -393,7 +350,7 @@ To handle aggregate operation, ensure that your API endpoint supports custom agg public object Post([FromBody] DataManagerRequest DataManagerRequest) { IEnumerable DataSource = GetOrderData(); - int count = DataSource.Cast().Count(); + int TotalRecordsCount = DataSource.Cast().Count(); // Handling Aggregation in UrlAdaptor. IDictionary Aggregates = null; if (DataManagerRequest.Aggregates != null) @@ -402,10 +359,12 @@ To handle aggregate operation, ensure that your API endpoint supports custom agg Aggregates = DataUtil.PerformAggregation(DataSource, DataManagerRequest.Aggregates); //Add custom logic here if needed and remove above method } - return new { result = DataSource, count = count, aggregates = Aggregates }; + return new { result = DataSource, count = TotalRecordsCount, aggregates = Aggregates }; } {% endhighlight %} +> The server-side management of the `PerformAggregation` method is necessary only for the [Footer Template](https://blazor.syncfusion.com/documentation/datagrid/footer-aggregate) aggregation. There is no need for explicit handling of the Aggregate operation for the [Group Footer template](https://blazor.syncfusion.com/documentation/datagrid/group-and-caption-aggregate#group-footer-aggregates) and [Group Caption template](https://blazor.syncfusion.com/documentation/datagrid/group-and-caption-aggregate#group-caption-aggregates). + ### Handling paging operation To handle paging operation, ensure that your API endpoint supports custom paging criteria. Implement the paging logic on the server-side using the [PerformTake](https://help.syncfusion.com/cr/blazor/Syncfusion.Blazor.DataOperations.html#Syncfusion_Blazor_DataOperations_PerformTake_System_Collections_IEnumerable_System_Int32_) and [PerformSkip](https://help.syncfusion.com/cr/blazor/Syncfusion.Blazor.DataOperations.html#Syncfusion_Blazor_DataOperations_PerformSkip__1_System_Collections_Generic_IEnumerable___0__System_Int32_) method from the [DataOperations](https://help.syncfusion.com/cr/blazor/Syncfusion.Blazor.DataOperations.html) class. This allows the custom data source to undergo paging based on the criteria specified in the incoming [DataManagerRequest](https://help.syncfusion.com/cr/blazor/Syncfusion.Blazor.DataManagerRequest.html) object. @@ -416,7 +375,7 @@ To handle paging operation, ensure that your API endpoint supports custom paging public object Post([FromBody] DataManagerRequest DataManagerRequest) { IEnumerable DataSource = GetOrderData(); - int count = DataSource.Cast().Count(); + int TotalRecordsCount = DataSource.Cast().Count(); // Handling Paging in UrlAdaptor. if (DataManagerRequest.Skip != 0) { @@ -429,7 +388,7 @@ public object Post([FromBody] DataManagerRequest DataManagerRequest) DataSource = DataOperations.PerformTake(DataSource, DataManagerRequest.Take); //Add custom logic here if needed and remove above method } - return new { result = DataSource, count = count }; + return new { result = DataSource, count = TotalRecordsCount }; } {% endhighlight %} @@ -439,7 +398,7 @@ public object Post([FromBody] DataManagerRequest DataManagerRequest) To enable editing in this Blazor DataGrid component, utilize the [GridEditSettings](https://help.syncfusion.com/cr/blazor/Syncfusion.Blazor.Grids.GridEditSettings.html) component. The Blazor DataGrid offers multiple edit modes including the [Inline/Normal](https://blazor.syncfusion.com/documentation/datagrid/in-line-editing), [Dialog](https://blazor.syncfusion.com/documentation/datagrid/dialog-editing), and [Batch](https://blazor.syncfusion.com/documentation/datagrid/batch-editing) editing. For more details, refer to the Blazor DataGrid component [editing](https://blazor.syncfusion.com/documentation/datagrid/editing) documentation. -In this scenario, the inline edit mode and [Toolbar](https://blazor.syncfusion.com/documentation/datagrid/tool-bar) property are configured to display toolbar items for editing purposes. +In this scenario, the inline edit `Mode` and [Toolbar](https://blazor.syncfusion.com/documentation/datagrid/tool-bar) property are configured to display toolbar items for editing purposes. {% tabs %} {% highlight razor %} @@ -782,8 +741,8 @@ This section describes step by step process how to retrieve data from a MySQL Se public override async Task ReadAsync(DataManagerRequest DataManagerRequest, string Key = null) { IEnumerable DataSource = await OrderService.GetOrdersAsync(); - int count = DataSource.Cast().Count(); - return DataManagerRequest.RequiresCounts ? new DataResult() { Result = DataSource, Count = count } : (object)DataSource; + int TotalRecordsCount = DataSource.Cast().Count(); + return DataManagerRequest.RequiresCounts ? new DataResult() { Result = DataSource, Count = TotalRecordsCount } : (object)DataSource; } } } @@ -850,8 +809,8 @@ public class CustomAdaptor : DataAdaptor DataSource = DataOperations.PerformSearching(DataSource, DataManagerRequest.Search); //Add custom logic here if needed and remove above method } - int count = DataSource.Cast().Count(); - return DataManagerRequest.RequiresCounts ? new DataResult() { Result = DataSource, Count = count } : (object)DataSource; + int TotalRecordsCount = DataSource.Cast().Count(); + return DataManagerRequest.RequiresCounts ? new DataResult() { Result = DataSource, Count = TotalRecordsCount } : (object)DataSource; } } {% endhighlight %} @@ -877,8 +836,8 @@ public class CustomAdaptor : DataAdaptor DataSource = DataOperations.PerformFiltering(DataSource, DataManagerRequest.Where, DataManagerRequest.Where[0].Operator); //Add custom logic here if needed and remove above method } - int count = DataSource.Cast().Count(); - return DataManagerRequest.RequiresCounts ? new DataResult() { Result = DataSource, Count = count } : (object)DataSource; + int TotalRecordsCount = DataSource.Cast().Count(); + return DataManagerRequest.RequiresCounts ? new DataResult() { Result = DataSource, Count = TotalRecordsCount } : (object)DataSource; } } {% endhighlight %} @@ -904,8 +863,8 @@ public class CustomAdaptor : DataAdaptor DataSource = DataOperations.PerformSorting(DataSource, DataManagerRequest.Sorted); //Add custom logic here if needed and remove above method } - int count = DataSource.Cast().Count(); - return DataManagerRequest.RequiresCounts ? new DataResult() { Result = DataSource, Count = count } : (object)DataSource; + int TotalRecordsCount = DataSource.Cast().Count(); + return DataManagerRequest.RequiresCounts ? new DataResult() { Result = DataSource, Count = TotalRecordsCount } : (object)DataSource; } } {% endhighlight %} @@ -924,7 +883,7 @@ public class CustomAdaptor : DataAdaptor public override async Task ReadAsync(DataManagerRequest DataManagerRequest, string Key = null) { IEnumerable DataSource = await OrderService.GetOrdersAsync(); - int count = DataSource.Cast().Count(); + int TotalRecordsCount = DataSource.Cast().Count(); // Handling Aggregation in CustomAdaptor. IDictionary Aggregates = null; if (DataManagerRequest.Aggregates != null) // Aggregation @@ -932,11 +891,13 @@ public class CustomAdaptor : DataAdaptor Aggregates = DataUtil.PerformAggregation(DataSource, DataManagerRequest.Aggregates); //Add custom logic here if needed and remove above method } - return DataManagerRequest.RequiresCounts ? new DataResult() { Result = DataSource, Count = count, Aggregates = Aggregates } : (object)DataSource; + return DataManagerRequest.RequiresCounts ? new DataResult() { Result = DataSource, Count = TotalRecordsCount, Aggregates = Aggregates } : (object)DataSource; } } {% endhighlight %} +> The server-side management of the `PerformAggregation` method is necessary only for the [Footer Template](https://blazor.syncfusion.com/documentation/datagrid/footer-aggregate) aggregation. There is no need for explicit handling of the Aggregate operation for the [Group Footer template](https://blazor.syncfusion.com/documentation/datagrid/group-and-caption-aggregate#group-footer-aggregates) and [Group Caption template](https://blazor.syncfusion.com/documentation/datagrid/group-and-caption-aggregate#group-caption-aggregates). + ### Handling paging operation When employing the `CustomAdaptor`, handling paging operation involves overriding the [Read](https://help.syncfusion.com/cr/blazor/Syncfusion.Blazor.DataAdaptor.html#Syncfusion_Blazor_DataAdaptor_Read_Syncfusion_Blazor_DataManagerRequest_System_String_) or [ReadAsync](https://help.syncfusion.com/cr/blazor/Syncfusion.Blazor.DataAdaptor.html#Syncfusion_Blazor_DataAdaptor_ReadAsync_Syncfusion_Blazor_DataManagerRequest_System_String_) method of the [DataAdaptor](https://help.syncfusion.com/cr/blazor/Syncfusion.Blazor.DataAdaptor.html) abstract class. @@ -951,7 +912,7 @@ public class CustomAdaptor : DataAdaptor public override async Task ReadAsync(DataManagerRequest DataManagerRequest, string Key = null) { IEnumerable DataSource = await OrderService.GetOrdersAsync(); - int count = DataSource.Cast().Count(); + int TotalRecordsCount = DataSource.Cast().Count(); // Handling paging in CustomAdaptor. if (DataManagerRequest.Skip != 0) { @@ -965,7 +926,7 @@ public class CustomAdaptor : DataAdaptor DataSource = DataOperations.PerformTake(DataSource, DataManagerRequest.Take); //Add custom logic here if needed and remove above method } - return DataManagerRequest.RequiresCounts ? new DataResult() { Result = DataSource, Count = count } : (object)DataSource; + return DataManagerRequest.RequiresCounts ? new DataResult() { Result = DataSource, Count = TotalRecordsCount } : (object)DataSource; } } {% endhighlight %} @@ -974,7 +935,7 @@ public class CustomAdaptor : DataAdaptor When employing `CustomAdaptor`, the grouping operation must be managed within the [Read](https://help.syncfusion.com/cr/blazor/Syncfusion.Blazor.DataAdaptor.html#Syncfusion_Blazor_DataAdaptor_Read_Syncfusion_Blazor_DataManagerRequest_System_String_) or [ReadAsync](https://help.syncfusion.com/cr/blazor/Syncfusion.Blazor.DataAdaptor.html#Syncfusion_Blazor_DataAdaptor_ReadAsync_Syncfusion_Blazor_DataManagerRequest_System_String_) method of the `CustomAdaptor`. -The provided sample code illustrated how to implement the grouping operation within `CustomAdaptor`, +In the code example below, grouping a custom data source can be achieved by utilizing the [Group](https://help.syncfusion.com/cr/blazor/Syncfusion.Blazor.Data.DataUtil.html#Syncfusion_Blazor_Data_DataUtil_Group__1_System_Collections_IEnumerable_System_String_System_Collections_Generic_List_Syncfusion_Blazor_Data_Aggregate__System_Int32_System_Collections_Generic_IDictionary_System_String_System_String__System_Boolean_System_Boolean_) method from the [DataUtil](https://help.syncfusion.com/cr/blazor/Syncfusion.Blazor.Data.DataUtil.html) class. Alternatively, you can use your own method for grouping operation and bind the resulting data to the Blazor DataGrid component. {% highlight razor %} public class CustomAdaptor : DataAdaptor @@ -984,7 +945,7 @@ public class CustomAdaptor : DataAdaptor public override async Task ReadAsync(DataManagerRequest DataManagerRequest, string Key = null) { IEnumerable DataSource = await OrderService.GetOrdersAsync(); - int count = DataSource.Cast().Count(); + int TotalRecordsCount = DataSource.Cast().Count(); DataResult DataObject = new DataResult(); // Handling Group operation in CustomAdaptor. if (DataManagerRequest.Group != null) @@ -997,10 +958,10 @@ public class CustomAdaptor : DataAdaptor //Add custom logic here if needed and remove above method } DataObject.Result = ResultData; - DataObject.Count = count; + DataObject.Count = TotalRecordsCount; return DataManagerRequest.RequiresCounts ? DataObject : (object)ResultData; } - return DataManagerRequest.RequiresCounts ? new DataResult() { Result = DataSource, Count = count } : (object)DataSource; + return DataManagerRequest.RequiresCounts ? new DataResult() { Result = DataSource, Count = TotalRecordsCount } : (object)DataSource; } } {% endhighlight %} @@ -1016,7 +977,7 @@ public class CustomAdaptor : DataAdaptor public override async Task ReadAsync(DataManagerRequest DataManagerRequest, string Key = null) { IEnumerable DataSource = await OrderService.GetOrdersAsync(); - int count = DataSource.Cast().Count(); + int TotalRecordsCount = DataSource.Cast().Count(); DataResult DataObject = new DataResult(); // Handling both Grouping and Aggregation in CustomAdaptor. if (DataManagerRequest.Aggregates != null || DataManagerRequest.Group != null) // Aggregation @@ -1036,12 +997,12 @@ public class CustomAdaptor : DataAdaptor { DataObject.Result = DataSource; } - DataObject.Count = count; + DataObject.Count = TotalRecordsCount; DataObject.Aggregates = DataUtil.PerformAggregation(DataSource, DataManagerRequest.Aggregates); return DataManagerRequest.RequiresCounts ? DataObject : (object)DataSource; } - return DataManagerRequest.RequiresCounts ? new DataResult() { Result = DataSource, Count = count } : (object)DataSource; + return DataManagerRequest.RequiresCounts ? new DataResult() { Result = DataSource, Count = TotalRecordsCount } : (object)DataSource; } } ``` @@ -1066,7 +1027,7 @@ In this scenario, the inline edit `Mode` and [Toolbar](https://blazor.syncfusion {% endhighlight %} -> * Inline/Normal editing is the default edit mode for the Blazor DataGrid component. To enable CRUD operations, ensure that the [IsPrimaryKey](https://help.syncfusion.com/cr/blazor/Syncfusion.Blazor.Grids.GridColumn.html#Syncfusion_Blazor_Grids_GridColumn_IsPrimaryKey) property is set to **true** for a specific `GridColumn`, ensuring that its value is unique. +> * Inline/Normal editing is the default edit [Mode](https://help.syncfusion.com/cr/blazor/Syncfusion.Blazor.Grids.GridEditSettings.html#Syncfusion_Blazor_Grids_GridEditSettings_Mode) for the Blazor DataGrid component. To enable CRUD operations, ensure that the [IsPrimaryKey](https://help.syncfusion.com/cr/blazor/Syncfusion.Blazor.Grids.GridColumn.html#Syncfusion_Blazor_Grids_GridColumn_IsPrimaryKey) property is set to **true** for a specific `GridColumn`, ensuring that its value is unique. > * If database has an Autogenerated column, ensure to define [IsIdentity](https://help.syncfusion.com/cr/blazor/Syncfusion.Blazor.Grids.GridColumn.html#Syncfusion_Blazor_Grids_GridColumn_IsIdentity) property of `GridColumn` to disable them during adding or editing operations. The CRUD operations can be performed and customized on our own by overriding the following CRUD methods of the [DataAdaptor](https://help.syncfusion.com/cr/blazor/Syncfusion.Blazor.DataAdaptor.html) abstract class.