diff --git a/blazor/datagrid/connecting-to-database/microsoft-sql-server.md b/blazor/datagrid/connecting-to-database/microsoft-sql-server.md index 59a06a5761..81f079ea93 100644 --- a/blazor/datagrid/connecting-to-database/microsoft-sql-server.md +++ b/blazor/datagrid/connecting-to-database/microsoft-sql-server.md @@ -1,7 +1,7 @@ --- layout: post title: Microsoft SQL Data Binding in Blazor DataGrid Component | Syncfusion -description: Learn about consuming data from SQL Server using Microsoft SQL Client, binding it to Syncfusion Component, and performing CRUD operations +description: Learn about consuming data from SQL Server using Microsoft SQL Client, binding it to Syncfusion Component, and performing CRUD operations. platform: Blazor control: DataGrid documentation: ug @@ -9,825 +9,793 @@ documentation: ug # Microsoft SQL Server Data Binding -This section describes how to use [System.Data.SqlClient](https://www.nuget.org/packages/System.Data.SqlClient/4.8.6?_src=template) to retrieve data from a Microsoft SQL server database and bind it to the Blazor DataGrid. +This section describes how to connect and retrieve data from a Microsoft SQL Server database using [System.Data.SqlClient](https://www.nuget.org/packages/System.Data.SqlClient/4.8.6?_src=template) and bind it to the Blazor DataGrid component. -Microsoft SQL database can be bound to the datagrid in different ways (i.e.) DataSource property, CustomAdaptor and Remote Databinding using various adaptors (WebAPI, OData, ODataV4, URLadaptor). Here listed two options are the most efficient and easily customizable approaches. [CustomAdaptor](https://blazor.syncfusion.com/documentation/datagrid/custom-binding) approach suitable to local binding and [URLAdaptor](https://blazor.syncfusion.com/documentation/data/adaptors#url-adaptor) suitable for remote data bidning. 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. +Microsoft SQL Server database can be bound to the Blazor DataGrid 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 (Web API, OData, ODataV4, Url, GraphQL). In this documentation, two approaches will be examined to connect a Microsoft SQL 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. -**Custom Adaptor** +* **Using UrlAdaptor** -A custom adaptor allows you to perform manual operations on the data. For implementing custom data binding in Grid, DataAdaptor class is used. It class acts as a base class and has both synchronous and asynchronous method signatures whcih can be overriden in **CustomAdaptor**. +In this approach, data can be bound to the Blazor DataGrid component by calling an existing pre-configured API service connected to the Microsoft SQL Server database. The Blazor DataGrid supports various adaptors to meet this requirement, such as [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). Among these, the [UrlAdaptor](https://blazor.syncfusion.com/documentation/data/adaptors#url-adaptor) serves as the base adaptor for interacting with remote data services. Hence, this approach is selected to meet the requirement. It is important to note that the UrlAdaptor forwards all requests to an API service as **POST** requests. -**API Services with URL Adaptor** +* **Using CustomAdaptor** -Remotely database can be bound to grid using multiple adaptors namely WebAPI, OData, ODataV4 including the URLAdaptor. If you have pre configured API service following existing WebAPI standards, then WebAPI adaptor can be utilized to achieve your requirement. The URL adaptor send all requests to API service as a **POST** request. The UrlAdaptor acts as the base adaptor for interacting with remote data services. +The [CustomAdaptor](https://blazor.syncfusion.com/documentation/datagrid/custom-binding) allows you to perform manual operation on the data for every action performed in Blazor DataGrid component. The [DataAdaptor](https://help.syncfusion.com/cr/blazor/Syncfusion.Blazor.DataAdaptor.html) class is used to achieve the custom data binding in Blazor DataGrid. This class acts as a base class and has both synchronous and asynchronous method signatures which can be overridden in `CustomAdaptor`. -## Binding data from Microsoft SQL Server using Custom Adaptor +## Binding data from Microsoft SQL Server using an API service -**1.** Create a simple Blazor DataGrid by following the [Getting Started](https://blazor.syncfusion.com/documentation/datagrid/getting-started-with-web-app) documentation link. +### Creating an API service -**2.** To connect a Microsoft SQL using the Microsoft SQL driver in our application, you need to install the [System.Data.SqlClient](https://www.nuget.org/packages/System.Data.SqlClient/4.8.6?_src=template) NuGet package. To do so, open the NuGet package manager of the project solution, search for the package **System.Data.SqlClient** and install it. +**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). -![Add the NuGet package System.Data.SqlClient to the project](../images/system-Data-sql-client-nuget-package-install.png) +**2.** To connect a Microsoft SQL Server database using the Microsoft SQL driver in your application, you need to install the [System.Data.SqlClient](https://www.nuget.org/packages/System.Data.SqlClient/4.8.6?_src=template) NuGet package. To add **System.Data.SqlClient** 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.** Next, in the **Index.razor** page, get the SQL data from the SQL server and bind it to the DataGrid component as a datasource by using the [CustomAdaptor](https://blazor.syncfusion.com/documentation/datagrid/custom-binding) feature. +**3.** Create an API controller (aka, GridController.cs) file under **Controllers** folder that helps to establish data communication with the Blazor DataGrid. -{% tabs %} -{% highlight razor tabtitle="Index.razor" %} -@rendermode InteractiveServer +**4.** In an API controller (aka, GridController), connect to Microsoft SQL Server. In the **Get()** method **SqlConnection** helps to connect the Microsoft SQL Server database. Next, using **SqlCommand** and **SqlDataAdapter** 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. -@using Syncfusion.Blazor.Grids -@using Syncfusion.Blazor.Data -@using Syncfusion.Blazor -@using Microsoft.Data.SqlClient; +{% tabs %} +{% highlight razor tabtitle="GridController.cs"%} +using Microsoft.AspNetCore.Mvc; +using System.Data; +using System.Data.SqlClient; +using Syncfusion.Blazor; +using Syncfusion.Blazor.Data; +using System.ComponentModel.DataAnnotations; +using Newtonsoft.Json; +namespace MyWebService.Controllers +{ + [ApiController] + public class GridController : ControllerBase + { + public static List Orders { get; set; } - - - - - - - - - - + public class Order + { + [Key] + public int? OrderID { get; set; } + public string? CustomerID { get; set; } + public int? EmployeeID { get; set; } + public decimal? Freight { get; set; } + public string? ShipCity { get; set; } + } -@code { - SfGrid Grid { get; set; } + [Route("api/[controller]")] + public List GetOrderData() + { + string ConnectionString = @""; + string QueryStr = "SELECT * FROM dbo.Orders ORDER BY OrderID;"; + SqlConnection sqlConnection = new(ConnectionString); + sqlConnection.Open(); + SqlCommand SqlCommand = new(QueryStr, sqlConnection); + SqlDataAdapter DataAdapter = new(SqlCommand); + DataTable DataTable = new(); + DataAdapter.Fill(DataTable); + sqlConnection.Close(); + var DataSource = (from DataRow Data in DataTable.Rows + select new Order() + { + OrderID = Convert.ToInt32(Data["OrderID"]), + CustomerID = Data["CustomerID"].ToString(), + EmployeeID = Convert.IsDBNull(Data["EmployeeID"]) ? 0 : Convert.ToUInt16(Data["EmployeeID"]), + ShipCity = Data["ShipCity"].ToString(), + Freight = Convert.ToDecimal(Data["Freight"]) + }).ToList(); + return DataSource; + } + } } {% endhighlight %} -{% highlight razor tabtitle="Orderdata.cs"%} - public class Order - { - public int? OrderID { get; set; } - public string CustomerID { get; set; } - public int EmployeeID { get; set; } - public decimal Freight { get; set; } - public string ShipCity { get; set; } - } -{% endhighlight %} {% endtabs %} -**4.** Within the custom adaptor’s [ReadAsync](https://help.syncfusion.com/cr/blazor/Syncfusion.Blazor.DataAdaptor.html#Syncfusion_Blazor_DataAdaptor_ReadAsync_Syncfusion_Blazor_DataManagerRequest_System_String_) method, leverage the [DataManagerRequest](https://help.syncfusion.com/cr/blazor/Syncfusion.Blazor.DataManagerRequest.html) to gather Grid action specifics such as paging, filtering, and sorting details. +**5.** Run the application and it will be hosted within the URL `https://localhost:xxxx`. + +**6.** Finally, the retrieved data from Microsoft SQL Server database which is in the form of JSON can be found in an API controller available in the URL link `https://localhost:xxxx/api/Grid`, as shown in the browser page below. -* Utilize the `DataManagerRequest` to formulate a SQL query string for paging purposes and execute the query. Fetch data from the database using the **SqlDataAdapter** class. +![Hosted API URL](../images/Ms-Sql-data.png) -* 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. +### Connecting Blazor DataGrid to an API service -* Finally, return the response as a `Result` and `Count` pair object in the **ReadAsync** method to bind the data to the DataGrid. +**1.** Create a simple Blazor DataGrid by following the [Getting Started](https://blazor.syncfusion.com/documentation/datagrid/getting-started-with-web-app) documentation link. In this Blazor web app, the `rendermode` is set as **InteractiveServer**. -{% tabs %} -{% highlight razor tabtitle="Index.razor" %} -@rendermode InteractiveServer +**2.** Map the hosted API's URL link `https://localhost:xxxx/api/Grid` to the Blazor DataGrid 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 API services. Below is an example of the [UrlAdaptor](https://blazor.syncfusion.com/documentation/data/adaptors#url-adaptor) configuration where an API services 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 services. 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 @using Microsoft.Data.SqlClient; - - - + + + - - + + @code { - 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(); - if (DataManagerRequest.Skip != 0) - { - //Paging - DataSource = DataOperations.PerformSkip(DataSource, DataManagerRequest.Skip); - } - if (DataManagerRequest.Take != 0) - { - DataSource = DataOperations.PerformTake(DataSource, DataManagerRequest.Take); - } - return DataManagerRequest.RequiresCounts ? new DataResult() { Result = DataSource, Count = count } : (object)DataSource; - } - } -} + SfGrid Grid { get; set; } + public List Orders { get; set; } -{% endhighlight %} -{% highlight razor tabtitle="Orderdata.cs" %} - public class OrderData - { - public async Task> GetOrdersAsync() - { - string connectionString = @""; - string QueryStr = "SELECT * FROM dbo.Orders ORDER BY OrderID;"; - List Orders = null; - using (SqlConnection connection = new SqlConnection(connectionString)) - { - SqlDataAdapter adapter = new SqlDataAdapter(QueryStr, connection); - DataSet data = new DataSet(); - connection.Open(); - // Using SqlDataAdapter, process the query string and fill the data into the dataset - adapter.Fill(data); - Orders = data.Tables[0].AsEnumerable().Select(r => new Order - { - OrderID = r.Field("OrderID"), - CustomerID = r.Field("CustomerID"), - EmployeeID = r.Field("EmployeeID"), - ShipCity = r.Field("ShipCity"), - Freight = r.Field("Freight") - }).ToList(); - connection.Close(); - } - return Orders; - } + public class Order + { + public int? OrderID { get; set; } + public string CustomerID { get; set; } + public int EmployeeID { get; set; } + public decimal Freight { get; set; } + public string ShipCity { get; set; } + } } {% endhighlight %} {% endtabs %} -> In the above grid, [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 grid will appear as depicted below. - -![Blazor Grid bound with Microsoft SQL data](../images/blazor-Grid-Ms-SQL-databinding.png) +> 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. -### Handling data operations +When you run the application, the resultant Blazor DataGrid will look like this -The Syncfusion Grid component offers a range of powerful features for handling grid actions such as **searching**, **sorting**,**filtering**,**paging** and **grouping**. This ensures efficient data retrieval and manipulation, providing a better user experience. Below are explanations on how to handle these data operations effectively in Custom Adaptor: +![Blazor DataGrid bound with Microsoft SQL Server data](../images/blazor-Grid-Ms-SQL-databinding.png) -**Perform Searching:** +> * The Syncfusion Blazor DataGrid component provides built-in support for handling various data operations such as **searching**, **sorting**, **filtering**, **paging**, and **grouping** on the server-side. These operations can be handled using methods such as `PerformSearching`, `PerformSorting`, `PerformFiltering`, `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. -When utlizing a custom adaptor, managing the searching operation ivolves 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** abstract class. +### Handling searching operation -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 grid. +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 %} -public class CustomAdaptor : DataAdaptor + +[HttpPost] +[Route("api/[controller]")] +public object Post([FromBody] DataManagerRequest DataManagerRequest) { - public OrderData OrderService = new OrderData(); - // Performs data Read operation - public override async Task ReadAsync(DataManagerRequest DataManagerRequest, string key = null) + IEnumerable DataSource = GetOrderData(); + if (DataManagerRequest.Search != null && DataManagerRequest.Search.Count > 0) { - IEnumerable DataSource = await OrderService.GetOrdersAsync(); - if (DataManagerRequest.Search != null && DataManagerRequest.Search.Count > 0) - { - // Searching - DataSource = DataOperations.PerformSearching(DataSource, DataManagerRequest.Search); - } - int count = DataSource.Cast().Count(); - return DataManagerRequest.RequiresCounts ? new DataResult() { Result = DataSource, Count = count } : (object)DataSource; + // Searching + DataSource = DataOperations.PerformSearching(DataSource, DataManagerRequest.Search); } + int count = DataSource.Cast().Count(); + return new { result = DataSource, count = count }; } {% endhighlight %} -**Perform Sorting:** - -When utlizing a custom adaptor, managing the sorting operation involves overriding the `Read` or `ReadAsync` method of the **DataAdaptor** abstract class. +### Handling filtering operation -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` class. Alternatively, you can implement your own method for sorting operation and bind the resulting data to the grid. +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 %} - - public class CustomAdaptor : DataAdaptor +[HttpPost] +[Route("api/[controller]")] +public object Post([FromBody] DataManagerRequest DataManagerRequest) { - public OrderData OrderService = new OrderData(); - // Performs data Read operation - public override async Task ReadAsync(DataManagerRequest DataManagerRequest, string key = null) + IEnumerable DataSource = GetOrderData(); + if (DataManagerRequest.Where != null && DataManagerRequest.Where.Count > 0) { - IEnumerable DataSource = await OrderService.GetOrdersAsync(); - if (DataManagerRequest.Sorted != null && DataManagerRequest.Sorted.Count > 0) - { - // Sorting - DataSource = DataOperations.PerformSorting(DataSource, DataManagerRequest.Sorted); - } - int count = DataSource.Cast().Count(); - return DataManagerRequest.RequiresCounts ? new DataResult() { Result = DataSource, Count = count } : (object)DataSource; + // Filtering + DataSource = DataOperations.PerformFiltering(DataSource, DataManagerRequest.Where, DataManagerRequest.Where[0].Operator); } + int count = DataSource.Cast().Count(); + return new { result = DataSource, count = count }; } {% endhighlight %} -**Perform Filtering:** +### Handling sorting operation -When employing a custom adaptor, handling the filtering operation involves overriding the `Read` or `ReadAsync` method of the **DataAdaptor** 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` class. Alternatively, you can implement your own method for filtering operations and bind the resulting data to the grid. +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 %} - - public class CustomAdaptor : DataAdaptor +[HttpPost] +[Route("api/[controller]")] +public object Post([FromBody] DataManagerRequest DataManagerRequest) { - public OrderData OrderService = new OrderData(); - // Performs data Read operation - public override async Task ReadAsync(DataManagerRequest DataManagerRequest, string key = null) + IEnumerable DataSource = GetOrderData(); + if (DataManagerRequest.Sorted != null && DataManagerRequest.Sorted.Count > 0) { - IEnumerable DataSource = await OrderService.GetOrdersAsync(); - if (DataManagerRequest.Where != null && DataManagerRequest.Where.Count > 0) - { - // Filtering - DataSource = DataOperations.PerformFiltering(DataSource, DataManagerRequest.Where, DataManagerRequest.Where[0].Operator); - } - int count = DataSource.Cast().Count(); - return DataManagerRequest.RequiresCounts ? new DataResult() { Result = DataSource, Count = count } : (object)DataSource; + // Sorting + DataSource = DataOperations.PerformSorting(DataSource, DataManagerRequest.Sorted); } + int count = DataSource.Cast().Count(); + return new { result = DataSource, count = count }; } - {% endhighlight %} -**Perform Paging:** - -When employing a custom adaptor, handling paging operation involves overriding the `Read` or `ReadAsync` method of the **DataAdaptor** abstract class. +### Handling paging operation -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` class. Alternatively, you can use your own method for paging operation and bind the resulting data to the grid. +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 %} - -public class CustomAdaptor : DataAdaptor +[HttpPost] +[Route("api/[controller]")] +public object Post([FromBody] DataManagerRequest DataManagerRequest) { - public OrderData OrderService = new OrderData(); - // Performs data Read operation - public override async Task ReadAsync(DataManagerRequest DataManagerRequest, string key = null) + IEnumerable DataSource = GetOrderData(); + int count = DataSource.Cast().Count(); + if (DataManagerRequest.Skip != 0) { - IEnumerable DataSource = await OrderService.GetOrdersAsync(); - int count = DataSource.Cast().Count(); - if (DataManagerRequest.Skip != 0) - { - //Paging - DataSource = DataOperations.PerformSkip(DataSource, DataManagerRequest.Skip); - } - if (DataManagerRequest.Take != 0) - { - DataSource = DataOperations.PerformTake(DataSource, DataManagerRequest.Take); - } - return DataManagerRequest.RequiresCounts ? new DataResult() { Result = DataSource, Count = count } : (object)DataSource; + // Paging + DataSource = DataOperations.PerformSkip(DataSource, DataManagerRequest.Skip); + } + if (DataManagerRequest.Take != 0) + { + DataSource = DataOperations.PerformTake(DataSource, DataManagerRequest.Take); } + return new { result = DataSource, count = count }; } {% endhighlight %} -**Perform Grouping:** +### Handling grouping operation -When employing Custom Adaptor, the grouping operation must be managed wihtin the `Read` or `ReadAsync` method of the Custom adaptor. - -The provided sample code illustrated how to implement the grouping operation wihtin in Custom Adaptor, +To handle grouping operation, ensure that your API endpoint supports custom grouping criteria. Implement the grouping logic on the server-side using the `Group` method from the [DataUtil](https://help.syncfusion.com/cr/blazor/Syncfusion.Blazor.Data.DataUtil.html) class. This allows the custom data source to undergo grouping based on the criteria specified in the incoming [DataManagerRequest](https://help.syncfusion.com/cr/blazor/Syncfusion.Blazor.DataManagerRequest.html) object. {% highlight razor %} -public class CustomAdaptor : DataAdaptor +[HttpPost] +[Route("api/[controller]")] +public object Post([FromBody] DataManagerRequest DataManagerRequest) { - public OrderData OrderService = new OrderData(); - // Performs data Read operation - public override async Task ReadAsync(DataManagerRequest DataManagerRequest, string key = null) + IEnumerable DataSource = GetOrderData(); + int count = DataSource.Cast().Count(); + DataResult DataObject = new DataResult(); + if (DataManagerRequest.Group != null) { - IEnumerable DataSource = await OrderService.GetOrdersAsync(); - int count = DataSource.Cast().Count(); - DataResult DataObject = new DataResult(); - if (DataManagerRequest.Group != null) + System.Collections.IEnumerable ResultData = DataSource.ToList(); + // Grouping + foreach (var group in DataManagerRequest.Group) { - IEnumerable ResultData = DataSource.ToList(); - // Grouping - foreach (var group in DataManagerRequest.Group) - { - ResultData = DataUtil.Group(ResultData, group, DataManagerRequest.Aggregates, 0, DataManagerRequest.GroupByFormatter); - } - DataObject.Result = ResultData; - DataObject.Count = count; - return DataManagerRequest.RequiresCounts ? DataObject : (object)ResultData; + ResultData = DataUtil.Group(ResultData, group, DataManagerRequest.Aggregates, 0, DataManagerRequest.GroupByFormatter); } - return DataManagerRequest.RequiresCounts ? new DataResult() { Result = DataSource, Count = count } : (object)DataSource; + DataObject.Result = ResultData; + DataObject.Count = count; + return DataManagerRequest.RequiresCounts ? DataObject : (object)ResultData; } + return new { result = DataSource, count = count }; } {% endhighlight %} -> For optimal performance, it is recommended to follow this sequence of operations(Searching, Filtering, Sorting, Paging, Grouping) in the `ReadAsync` method +> For optimal performance, it is recommended to follow this sequence of operations(Searching, Filtering, Sorting, Paging, 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 +### Handling CRUD operations -To enable editing in the grid component, utilize the [GridEditSettings](https://help.syncfusion.com/cr/blazor/Syncfusion.Blazor.Grids.GridEditSettings.html) component. The grid offers multiple editing modes including the Inline/Normal, Dialog and Batch editing. For more details, refer to the grid [editing](https://blazor.syncfusion.com/documentation/datagrid/editing) documentation. +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 [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 dispaly toolbar items for editing pruposes. +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 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 have AutoGenerated column, kinldy 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 while adding or editing operations. - -The CRUD operations can be performed and customized on our own by overriding the following CRUD methods of the **DataAdaptor** abstract class. - -* Insert/InsertAsync -* Remove/RemoveAsync -* Update/UpdateAsync -* BatchUpdate/BatchUpdateAsync - -Let’s see how to perform CRUD operation using SQL server data with Syncfusion Blazor DataGrid component. +> * 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 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 custom adaptor. Then, integrate the following code snippet into the **CustomAdaptor** class. The above code snippet demonstrated how to handle the insertion of new records within the `InsertAsync` method of CustomAdaptor component. Adjust the login inside this method as per your application requirements. +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 in the Orders table by calling the following **POST** method of an API. {% tabs %} -{% highlight razor tabtitle="Index.razor"%} - -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 grid. - await OrderService.AddOrderAsync(Value as Order); - return Value; -} - -{% endhighlight %} -{% highlight razor tabtitle="Orderdata.cs"%} - public async Task AddOrderAsync(Order Value) +{% highlight c# tabtitle="OrdersController.cs" %} + [HttpPost] +[Route("api/Grid/Insert")] +public void Insert([FromBody] CRUDModel Value) { - string ConnectionString = $""; - string Query = $"Insert into Orders(CustomerID,Freight,ShipCity,EmployeeID) values('{(Value as Order).CustomerID}','{(Value as Order).Freight}','{(Value as Order).ShipCity}','{(Value as Order).EmployeeID}')"; - SqlConnection Connection = new SqlConnection(ConnectionString); - Connection.Open(); - SqlCommand Command = new SqlCommand(Query, Connection); - Command.ExecuteNonQuery(); - Connection.Close(); + string ConnectionString = @""; + string Query = $"Insert into Orders(CustomerID,Freight,ShipCity,EmployeeID) values('{Value.Value.CustomerID}','{Value.Value.Freight}','{Value.Value.ShipCity}','{Value.Value.EmployeeID}')"; + SqlConnection SqlConnection = new SqlConnection(ConnectionString); + SqlConnection.Open(); + SqlCommand SqlCommand = new SqlCommand(Query, SqlConnection); + SqlCommand.ExecuteNonQuery(); + SqlConnection.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 custom adaptor. Then, integrate the following code snippet into the **CustomAdaptor** class. This code snippet demonstrated how to handle the updating of existing records within the `UpdateAsync` method of the CustomAdaptor component. Adjust the login insdie this method as per your application requirements. +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 razor tabtitle="Index.razor"%} - -// Performs Update operation - 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 in the grid. - await OrderService.UpdateOrderAsync(Value as Order); - return Value; - } -{% endhighlight %} -{% highlight razor tabtitle="Orderdata.cs"%} - public async Task UpdateOrderAsync(Order Value) +{% highlight c# tabtitle="OrdersController.cs" %} +[HttpPost] +[Route("api/Grid/Update")] +public void Update([FromBody] CRUDModel Value) { - string ConnectionString = $""; - SqlConnection Connection = new SqlConnection(ConnectionString); - Connection.Open(); - SqlCommand Command = new SqlCommand(Query, Connection); - Command.ExecuteNonQuery(); - Connection.Close(); + string ConnectionString = @""; + string Query = $"Update Orders set CustomerID='{Value.Value.CustomerID}', Freight='{Value.Value.Freight}', EmployeeID='{Value.Value.EmployeeID}', ShipCity='{Value.Value.ShipCity}' where OrderID='{Value.Value.OrderID}'"; + SqlConnection SqlConnection = new SqlConnection(ConnectionString); + SqlConnection.Open(); + SqlCommand SqlCommand = new SqlCommand(Query, SqlConnection); + SqlCommand.ExecuteNonQuery(); + SqlConnection.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 custom adaptor. Below is the code snippet that you can add to **CustomAdaptor** class. This code snippet demonstrated how to handle the deletion of existing records within the `RemoveAsync` method of custom adaptor component. Adjust the logic inside this method according to your application requirements. +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 razor tabtitle="Index.razor"%} - - public override async Task RemoveAsync(DataManager DataManager, object Value, string keyField, string key) +{% highlight c# tabtitle="OrdersController.cs" %} + [HttpPost] + [Route("api/Grid/Delete")] + public void Delete([FromBody] CRUDModel Value) { - //Add your delete logic here - //This method will be invoked when deleting existing records from the grid. - await OrderService.RemoveOrderAsync(Value as int?); - return Value; + string ConnectionString = @""; + string Query = $"Delete from Orders where OrderID={Value.Key}"; + SqlConnection SqlConnection = new SqlConnection(ConnectionString); + SqlConnection.Open(); + SqlCommand SqlCommand = new SqlCommand(Query, SqlConnection); + SqlCommand.ExecuteNonQuery(); + SqlConnection.Close(); } {% endhighlight %} -{% highlight razor tabtitle="Orderdata.cs"%} - public async Task RemoveOrderAsync(int? Key) - { - string ConnectionString = $""; - string Query = $"Delete from Orders where OrderID={Key}"; - SqlConnection Connection = new SqlConnection(ConnectionString); - Connection.Open(); - SqlCommand Command = new SqlCommand(Query, Connection); - Command.ExecuteNonQuery(); - Connection.Close(); - } -{% endhighlight %} {% endtabs %} -**Batch Operation** +**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 custom adaptor and add the following code in the custom adaptor. +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 %} // Performs BatchUpdate operation - 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 %} - -> You can find the sample in this [GitHub location](https://github.com/SyncfusionExamples/blazor-grid-mssql-connectivity-using-custom-adaptor). - -## Binding data from Microsoft SQL Server using an API service - -### 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). - -![Create ASP.NET Core Web App project](../images/azure-asp-core-web-service-create.png) - -**2.** To connect a Microsoft SQL using the **System.Data.SqlClient** in our application, we need to install the [System.Data.SqlClient](https://www.nuget.org/packages/System.Data.SqlClient/4.8.6?_src=template) NuGet package. To do so, open the NuGet package manager of the project solution, search for the package **System.Data.SqlClient** and install it. - -![Add the NuGet package Sytem.Data.SqlClient to the project](../images/system-Data-sql-client-nuget-package-install.png) - -**3.** Create a API controller (aka, GridController.cs) file under **Controllers** folder that helps to establish data communication with the DataGrid. - -**4.** In the API controller (aka, GridController), connect to Microsoft SQL server. In the **Get()** method **SqlConnection** helps to connect the SQL database (that is, Database1.mdf). Next, using **SqlCommand** and **SqlDataAdapter** 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 System.Data; -using System.Data.SqlClient; -using Syncfusion.Blazor; -using Syncfusion.Blazor.Data; -using System.ComponentModel.DataAnnotations; -using Newtonsoft.Json; -namespace MyWebService.Controllers +[HttpPost] +[Route("api/Grid/Batch")] +public void Batch([FromBody] CRUDModel Value) { - [ApiController] - public class GridController : ControllerBase + if (Value.Changed != null) { - public static List Orders { get; set; } - public class Order + foreach (var record in (IEnumerable)Value.Changed) { - [Key] - public int? OrderID { get; set; } - public string? CustomerID { get; set; } - public int? EmployeeID { get; set; } - public decimal? Freight { get; set; } - public string? ShipCity { get; set; } + //update in your database } - [Route("api/[controller]")] - public List GetOrderData() + } + if (Value.Added != null) + { + foreach (var record in (IEnumerable)Value.Added) { - string ConnectionString = @""; - string QueryStr = "SELECT * FROM dbo.Orders ORDER BY OrderID;"; - SqlConnection sqlConnection = new(ConnectionString); - sqlConnection.Open(); - SqlCommand SqlCommand = new(QueryStr, sqlConnection); - SqlDataAdapter DataAdapter = new(SqlCommand); - DataTable DataTable = new(); - DataAdapter.Fill(DataTable); - sqlConnection.Close(); - var DataSource = (from DataRow Data in DataTable.Rows - select new Order() - { - OrderID = Convert.ToInt32(Data["OrderID"]), - CustomerID = Data["CustomerID"].ToString(), - EmployeeID = Convert.IsDBNull(Data["EmployeeID"]) ? 0 : Convert.ToUInt16(Data["EmployeeID"]), - ShipCity = Data["ShipCity"].ToString(), - Freight = Convert.ToDecimal(Data["Freight"]) - }).ToList(); - return DataSource; - } + //Insert in your database + } + } + if (Value.Deleted != null) + { + foreach (var record in (IEnumerable)Value.Deleted) + { + //remove the records from your database + } } } {% endhighlight %} -{% endtabs %} -**5.** Run the application and it will be hosted within the URL `https://localhost:xxxx`. +> Find the sample from this [Github location](https://github.com/SyncfusionExamples/blazor-grid-mssql-connectivity-using-api-service). -**6.** Finally, the retrieved data from Microsoft SQL database which is in the form of JSON can be found in the API controller available in the URL link `https://localhost:xxxx/api/Grid`, as shown in the browser page below. +## Binding data from Microsoft SQL Server using CustomAdaptor -![Hosted API URL](../images/Ms-Sql-data.png) +**1.** Create a simple Blazor DataGrid by following the [Getting Started](https://blazor.syncfusion.com/documentation/datagrid/getting-started-with-web-app) documentation link. In this Blazor web app, the `rendermode` is set as **InteractiveServer**. + +**2.** To connect a Microsoft SQL Server database using the Microsoft SQL driver in your application, you need to install the [System.Data.SqlClient](https://www.nuget.org/packages/System.Data.SqlClient/4.8.6?_src=template) NuGet package. To add **System.Data.SqlClient** 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 Microsoft.Data.SqlClient; -### Connecting Grid to an API service + + + + + + + + + + + + +@code { + SfGrid Grid { get; set; } +} +{% endhighlight %} +{% highlight razor tabtitle="Orderdata.cs"%} + public class Order + { + public int? OrderID { get; set; } + public string CustomerID { get; set; } + public int EmployeeID { get; set; } + public decimal Freight { get; set; } + public string ShipCity { get; set; } + } +{% endhighlight %} +{% endtabs %} -**1.** Create a simple Blazor Grid by following the [Getting Started](https://blazor.syncfusion.com/documentation/datagrid/getting-started-with-web-app) documentation link. +**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. -**2.** Map the hosted API's URL link `https://localhost:xxxx/api/Grid` to the Grid 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**. +* In this `GetOrdersAsync` method, the Microsoft SQL Server database data is fetch by using the **SqlDataAdapter** class. -**3.** The `SfDataManager` offers mulitple adaptor options to connect with remote datasource based on API services. Below demonstrated is the `URLAdaptor` where API services is configured to return the resuting data in `Result` and `Count` format. +* 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. -**4.** The `UrlAdaptor` acts as the base adaptor for interacting with remote data services. Most of the built-in adaptors are derived from the `UrlAdaptor`. +* 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"%} +{% highlight razor tabtitle="Index.razor" %} +@rendermode InteractiveServer + @using Syncfusion.Blazor.Grids @using Syncfusion.Blazor.Data @using Syncfusion.Blazor @using Microsoft.Data.SqlClient; - - - + + + - - + + @code { - SfGrid Grid { get; set; } - public List Orders { get; set; } - - public class Order + public class CustomAdaptor : DataAdaptor { - public int? OrderID { get; set; } - public string CustomerID { get; set; } - public int EmployeeID { get; set; } - public decimal Freight { get; set; } - public string ShipCity { get; set; } + 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(); + return DataManagerRequest.RequiresCounts ? new DataResult() { Result = DataSource, Count = count } : (object)DataSource; + } + } +} +{% endhighlight %} +{% highlight razor tabtitle="OrderData.cs" %} +public class OrderData +{ + public async Task> GetOrdersAsync() + { + string connectionString = @""; + string QueryStr = "SELECT * FROM dbo.Orders ORDER BY OrderID;"; + List Orders = null; + using (SqlConnection connection = new SqlConnection(connectionString)) + { + SqlDataAdapter adapter = new SqlDataAdapter(QueryStr, connection); + DataSet data = new DataSet(); + connection.Open(); + // Using SqlDataAdapter, process the query string and fill the data into the dataset + adapter.Fill(data); + Orders = data.Tables[0].AsEnumerable().Select(r => new Order + { + OrderID = r.Field("OrderID"), + CustomerID = r.Field("CustomerID"), + EmployeeID = r.Field("EmployeeID"), + ShipCity = r.Field("ShipCity"), + Freight = r.Field("Freight") + }).ToList(); + connection.Close(); + } + return Orders; } } {% endhighlight %} {% endtabs %} -> In the above grid, `AllowSearching`, `AllowSorting`, `AllowFiltering`,`AllowPaging`, `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 Grid will look like this - -![Blazor Grid bound with Microsoft SQL data](../images/blazor-Grid-Ms-SQL-databinding.png) +> * The `DataManagerRequest` encompasses details about the Blazor DataGrid actions such as searching, filtering, sorting, 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. -### Handling data operations +When the application is executed, the Blazor DataGrid will appear as depicted below. -The Syncfusion Grid component provides built-in support for handling various data operations, including **searching**, **sorting**, **filtering**, **paging**, and **grouping**, on the server-side. These operations can be effectively managed using methods such as `PerformSearching`, `PerformSorting`, `PerformFiltering`, `PerformTake`, and `PerformSkip`, available in the **Syncfusion.Blazor.Data** package. By utilizing these methods, efficient data retrieval and manipulation are ensured, resulting in an enhanced user experience. Below, we'll delve into how to effectively handle these data operations using the Url Adaptor. +![Blazor DataGrid bound with Microsoft SQL Server data](../images/blazor-Grid-Ms-SQL-databinding.png) -> Ensure to refer** Syncfusion.Blazor.Data** nuget package in an API service project +### Handling searching operation -**Perform Searching:** +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. -To handle searching operations, 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** object. +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. {% highlight razor %} - - [HttpPost] -[Route("api/[controller]")] - public object Post([FromBody] DataManagerRequest DataManagerRequest) +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 = GetOrderData(); + IEnumerable DataSource = await OrderService.GetOrdersAsync(); if (DataManagerRequest.Search != null && DataManagerRequest.Search.Count > 0) { // Searching DataSource = DataOperations.PerformSearching(DataSource, DataManagerRequest.Search); } int count = DataSource.Cast().Count(); - return new { result = DataSource, count = count }; + return DataManagerRequest.RequiresCounts ? new DataResult() { Result = DataSource, Count = count } : (object)DataSource; } - +} {% endhighlight %} -**Perform Sorting:** +### 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. -To handle sorting operations, 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` class. This allows the custom data source to undergo sorting based on the criteria specified in the incoming **DataManagerRequest** object. +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. {% highlight razor %} - [HttpPost] - [Route("api/[controller]")] - public object Post([FromBody] DataManagerRequest DataManagerRequest) - { - IEnumerable DataSource = GetOrderData(); - if (DataManagerRequest.Sorted != null && DataManagerRequest.Sorted.Count > 0) - { - // Sorting - DataSource = DataOperations.PerformSorting(DataSource, DataManagerRequest.Sorted); - } - int count = DataSource.Cast().Count(); - return new { result = DataSource, count = count }; - } +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(); + if (DataManagerRequest.Where != null && DataManagerRequest.Where.Count > 0) + { + // Filtering + DataSource = DataOperations.PerformFiltering(DataSource, DataManagerRequest.Where, DataManagerRequest.Where[0].Operator); + } + int count = DataSource.Cast().Count(); + return DataManagerRequest.RequiresCounts ? new DataResult() { Result = DataSource, Count = count } : (object)DataSource; + } +} {% endhighlight %} -**Perform Filtering:** +### 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. -To handle filtering operations, 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` class. This allows the custom data source to undergo filtering based on the criteria specified in the incoming **DataManagerRequest** object. +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. {% highlight razor %} - [HttpPost] - [Route("api/[controller]")] - public object Post([FromBody] DataManagerRequest DataManagerRequest) - { - IEnumerable DataSource = GetOrderData(); - if (DataManagerRequest.Where != null && DataManagerRequest.Where.Count > 0) - { - // Filtering - DataSource = DataOperations.PerformFiltering(DataSource, DataManagerRequest.Where, DataManagerRequest.Where[0].Operator); - } - int count = DataSource.Cast().Count(); - return new { result = DataSource, count = count }; - } +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(); + if (DataManagerRequest.Sorted != null && DataManagerRequest.Sorted.Count > 0) + { + // Sorting + DataSource = DataOperations.PerformSorting(DataSource, DataManagerRequest.Sorted); + } + int count = DataSource.Cast().Count(); + return DataManagerRequest.RequiresCounts ? new DataResult() { Result = DataSource, Count = count } : (object)DataSource; + } +} {% endhighlight %} -**Perform Paging:** +### Handling paging operation -To handle paging operations, 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` class. This allows the custom data source to undergo paging based on the criteria specified in the incoming **DataManagerRequest** object. +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. {% highlight razor %} - [HttpPost] - [Route("api/[controller]")] - public object Post([FromBody] DataManagerRequest DataManagerRequest) - { - IEnumerable DataSource = GetOrderData(); - int count = DataSource.Cast().Count(); - - if (DataManagerRequest.Skip != 0) - { - // Paging - DataSource = DataOperations.PerformSkip(DataSource, DataManagerRequest.Skip); - } - if (DataManagerRequest.Take != 0) - { - DataSource = DataOperations.PerformTake(DataSource, DataManagerRequest.Take); - } - return new { result = DataSource, count = count }; - } +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(); + if (DataManagerRequest.Skip != 0) + { + // Paging + DataSource = DataOperations.PerformSkip(DataSource, DataManagerRequest.Skip); + } + if (DataManagerRequest.Take != 0) + { + // Taking + DataSource = DataOperations.PerformTake(DataSource, DataManagerRequest.Take); + } + return DataManagerRequest.RequiresCounts ? new DataResult() { Result = DataSource, Count = count } : (object)DataSource; + } +} {% endhighlight %} -**Perform Grouping:** +### Handling grouping operation -To handle grouping operations, ensure that your API endpoint supports custom grouping criteria. Implement the grouping logic on the server-side using the `Group` method from the [DataUtil](https://help.syncfusion.com/cr/blazor/Syncfusion.Blazor.Data.DataUtil.html) class. This allows the custom data source to undergo grouping based on the criteria specified in the incoming **DataManagerRequest** object. +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 %} - [HttpPost] - [Route("api/[controller]")] - [HttpPost] - [Route("api/[controller]")] - public object Post([FromBody] DataManagerRequest DataManagerRequest) - { - IEnumerable DataSource = GetOrderData(); - int count = DataSource.Cast().Count(); - DataResult DataObject = new DataResult(); - if (DataManagerRequest.Group != null) - { - System.Collections.IEnumerable ResultData = DataSource.ToList(); - // Grouping - foreach (var group in DataManagerRequest.Group) - { - ResultData = DataUtil.Group(ResultData, group, DataManagerRequest.Aggregates, 0, DataManagerRequest.GroupByFormatter); - } - DataObject.Result = ResultData; - DataObject.Count = count; - return DataManagerRequest.RequiresCounts ? DataObject : (object)ResultData; - } - return new { result = DataSource, count = count }; - } +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(); + 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); + } + 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(Search, Filter, Sort, Paging, Grouping) in the **ReadAsync** method +> For optimal performance, it is recommended to follow this sequence of operations(Searching, Filtering, Sorting, Paging, Grouping) in the `ReadAsync` method -### Handling CRUD operations +### Handling CRUD operations -To enable editing in this grid component, utilize the [GridEditSettings](https://help.syncfusion.com/cr/blazor/Syncfusion.Blazor.Grids.GridEditSettings.html) component. The grid offers multiple editing 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 grid [editing](https://blazor.syncfusion.com/documentation/datagrid/editing) documentation. +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 offers multiple edit modes including the Inline/Normal, Dialog and Batch editing. For more details, refer to the Blazor DataGrid [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 configured to display toolbar items for editing purpose. -{% tabs %} {% highlight razor %} - - - - - - - - - - + + {% endhighlight %} -{% endtabs %} -> * Normal editing is the default edit mode for the 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 have AutoGenerated column, kinldy 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 while adding or editing operations. +> * 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 Microsoft SQL Server data with Syncfusion Blazor DataGrid component. **Insert Operation:** -To insert a new row, simply click the **Add** toolbar button. The new records edit form will be dispalyed as shown below. Upon clicking the **Update** toolbar button, record will inserted into in the Orders table by calling the following **POST** method of the API. +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 c# tabtitle="OrdersController.cs" %} - [HttpPost] - [Route("api/Grid/Insert")] - public void Insert([FromBody] CRUDModel Value) - { - string ConnectionString = @""; - string Query = $"Insert into Orders(CustomerID,Freight,ShipCity,EmployeeID) values('{Value.Value.CustomerID}','{Value.Value.Freight}','{Value.Value.ShipCity}','{Value.Value.EmployeeID}')"; - SqlConnection SqlConnection = new SqlConnection(ConnectionString); - SqlConnection.Open(); - SqlCommand SqlCommand = new SqlCommand(Query, SqlConnection); - SqlCommand.ExecuteNonQuery(); - SqlConnection.Close(); - } +{% highlight razor tabtitle="Index.razor"%} +// Perform Insert operation +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. + await OrderService.AddOrderAsync(Value as Order); + return Value; +} +{% endhighlight %} +{% highlight razor tabtitle="Orderdata.cs"%} +public async Task AddOrderAsync(Order Value) +{ + string ConnectionString = $""; + string Query = $"Insert into Orders(CustomerID, Freight, ShipCity, EmployeeID) values('{Value.CustomerID}', '{Value.Freight}', '{Value.ShipCity}', '{Value.EmployeeID}')"; + SqlConnection Connection = new SqlConnection(ConnectionString); + Connection.Open(); + SqlCommand Command = new SqlCommand(Query, Connection); + Command.ExecuteNonQuery(); + Connection.Close(); +} {% endhighlight %} {% endtabs %} **Update Operation:** -To edit a row, first select desrired row and click the **Edit** toolbar button. The edit form will be displayed as shown below. proceed to modify the CustomerName column as needed. Clicking the **Update** toolbar button will update the edit record in the Orders table by involing the following **Post** method of the API. +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 c# tabtitle="OrdersController.cs" %} -[HttpPost] -[Route("api/Grid/Update")] -public void Update([FromBody] CRUDModel Value) +{% highlight razor tabtitle="Index.razor"%} +// Perform Update operation +public override async Task UpdateAsync(DataManager DataManager, object Value, string keyField, string key) { - string ConnectionString = @""; - string Query = $"Update Orders set CustomerID='{Value.Value.CustomerID}', Freight='{Value.Value.Freight}',EmployeeID='{Value.Value.EmployeeID}',ShipCity='{Value.Value.ShipCity}' where OrderID='{Value.Value.OrderID}'"; - SqlConnection SqlConnection = new SqlConnection(ConnectionString); - SqlConnection.Open(); - SqlCommand SqlCommand = new SqlCommand(Query, SqlConnection); - SqlCommand.ExecuteNonQuery(); - SqlConnection.Close(); + // Add your update logic here + // This method will be invoked when updating existing records in the Blazor DataGrid. + await OrderService.UpdateOrderAsync(Value as Order); + return Value; +} +{% endhighlight %} +{% highlight razor tabtitle="Orderdata.cs"%} + public async Task UpdateOrderAsync(Order Value) +{ + string ConnectionString = $""; + SqlConnection Connection = new SqlConnection(ConnectionString); + Connection.Open(); + SqlCommand Command = new SqlCommand(Query, Connection); + Command.ExecuteNonQuery(); + Connection.Close(); } {% endhighlight %} {% endtabs %} **Delete Operation:** -To delete a row, simply select the desrired row and click the **Delete** toolbar button. This action will trigger a **DELETE** request to the API, containing the primary key value of the selected record. As a result corresponding record will be removed from the Orders table. +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 c# tabtitle="OrdersController.cs" %} - [HttpPost] - [Route("api/Grid/Delete")] - public void Delete([FromBody] CRUDModel Value) +{% highlight razor tabtitle="Index.razor"%} +// Perform Delete operation +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. + await OrderService.RemoveOrderAsync(Value as int?); + return Value; +} +{% endhighlight %} +{% highlight razor tabtitle="Orderdata.cs"%} + public async Task RemoveOrderAsync(int? Key) { - string ConnectionString = @""; - string Query = $"Delete from Orders where OrderID={Value.Key}"; - SqlConnection SqlConnection = new SqlConnection(ConnectionString); - SqlConnection.Open(); - SqlCommand SqlCommand = new SqlCommand(Query, SqlConnection); - SqlCommand.ExecuteNonQuery(); - SqlConnection.Close(); - } + string ConnectionString = $""; + string Query = $"Delete from Orders where OrderID={Key}"; + SqlConnection Connection = new SqlConnection(ConnectionString); + Connection.Open(); + SqlCommand Command = new SqlCommand(Query, Connection); + Command.ExecuteNonQuery(); + Connection.Close(); + } {% endhighlight %} {% endtabs %} -**Batch Operation** +**Batch Operation:** -To perform Batch Operations, define the Edit 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 rows in batch 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 mode. Clicking the "Update" toolbar button will update the newly added, edited records, or deleted records from the Orders table using a single API **POST** request. +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 %} - // Performs BatchUpdate operation -[HttpPost] -[Route("api/Grid/Batch")] -public void Batch([FromBody] CRUDModel Value) +// Perform BatchUpdate operation +public override async Task BatchUpdateAsync(DataManager DataManager, object Changed, object Added, object Deleted, string KeyField, string Key, int? dropIndex) { - if (Value.Changed != null) + if (Changed != null) { - foreach (var record in (IEnumerable)Value.Changed) + foreach (var record in (IEnumerable)Changed) { - //update in your database + await OrderService.UpdateOrderAsync(record as Order); } - } - if (Value.Added != null) + if (Added != null) { - foreach (var record in (IEnumerable)Value.Added) + foreach (var record in (IEnumerable)Added) { - //Insert in your database + await OrderService.AddOrderAsync(record as Order); } - } - if (Value.Deleted != null) + if (Deleted != null) { - foreach (var record in (IEnumerable)Value.Deleted) + foreach (var record in (IEnumerable)Deleted) { - //remove the records from your database + await OrderService.RemoveOrderAsync((record as Order).OrderID); } } + return Key; } {% endhighlight %} -> Find the sample from this [Github location](https://github.com/SyncfusionExamples/blazor-grid-mssql-connectivity-using-api-service). +> You can find the sample in this [GitHub location](https://github.com/SyncfusionExamples/blazor-grid-mssql-connectivity-using-custom-adaptor). diff --git a/blazor/datagrid/images/Ms-Sql-data.png b/blazor/datagrid/images/Ms-Sql-data.png index 7cd02224df..e7cdc38b5d 100644 Binary files a/blazor/datagrid/images/Ms-Sql-data.png and b/blazor/datagrid/images/Ms-Sql-data.png differ diff --git a/blazor/datagrid/images/blazor-Grid-Ms-SQL-databinding.png b/blazor/datagrid/images/blazor-Grid-Ms-SQL-databinding.png index 1bfda01810..0bcee6a3d7 100644 Binary files a/blazor/datagrid/images/blazor-Grid-Ms-SQL-databinding.png and b/blazor/datagrid/images/blazor-Grid-Ms-SQL-databinding.png differ