diff --git a/blazor/datagrid/connecting-to-database/mysql-server.md b/blazor/datagrid/connecting-to-database/mysql-server.md index fcd1125fea..1171ffaad6 100644 --- a/blazor/datagrid/connecting-to-database/mysql-server.md +++ b/blazor/datagrid/connecting-to-database/mysql-server.md @@ -1,1245 +1,1000 @@ --- layout: post -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. +title: MySQL Server Data Binding in Blazor DataGrid using Entity Framework | Syncfusion +description: Learn about connecting MySQL Server with Entity Framework Core and binding data to Syncfusion Blazor DataGrid with complete CRUD operations. platform: Blazor control: DataGrid documentation: ug --- -# Connecting MySQL Server data in to Blazor DataGrid Component +# Connecting MySQL Server data to Blazor DataGrid + +[Syncfusion® Blazor DataGrid](https://www.syncfusion.com/blazor-components/blazor-datagrid) supports binding data from a MySQL Server database using Entity Framework Core (EF Core). This modern approach provides a more maintainable and type-safe alternative to raw SQL queries. + +Entity Framework Core is an Object-Relational Mapper (ORM) that simplifies database operations by: +- Automatic SQL Generation: EF Core generates optimized SQL queries automatically. +- Type Safety: Work with strongly-typed objects instead of raw SQL strings. +- Built-in Protections: Automatic parameterization prevents SQL injection attacks. +- Migration Support: Manage database schema changes version-by-version. +- LINQ Queries: Use familiar LINQ syntax instead of SQL strings. + +## Prerequisites + +Ensure the following software and packages are installed before proceeding: + +| Software/Package | Version | Purpose | +|-----------------|---------|---------| +| Visual Studio 2022 | 17.0 or later | Development IDE with Blazor workload | +| .NET SDK | net8.0 or compatible | Runtime and build tools | +| MySQL Server| 8.0.41 or later | Database server | +| Syncfusion.Blazor | 28.1.33 or later | DataGrid and UI components | +| Microsoft.EntityFrameworkCore | 9.0.0 or later | Defining DbContext and running LINQ queries | +| Pomelo.EntityFrameworkCore.MySql | 9.0.0 or later | MySQL EF Core provider | + +## MySQL server environment + +This project uses a MySQL database with Entity Framework Core (Pomelo) to store and manage payment transaction records and to support server-side CRUD, searching, filtering, sorting, grouping, and paging for the transactions table. + +### Step 1: Create database and table in MySQL Server + +Create a MySQL database named **transactiondb** and define a **transactions** table schema to store payment records. After that, insert a few sample records into the transactions table. Run the script below in MySQL Workbench. + +```sql +-- Create Database +CREATE DATABASE IF NOT EXISTS transactiondb; +USE transactiondb; + +-- Create Transaction Table +CREATE TABLE IF NOT EXISTS transactions ( +Id INT AUTO_INCREMENT PRIMARY KEY, +TransactionId VARCHAR(50) NOT NULL UNIQUE, +CustomerId INT NOT NULL, +OrderId INT NULL, +InvoiceNumber VARCHAR(50) NULL, +Description VARCHAR(500) NULL, +Amount DECIMAL(15, 2) NOT NULL, +CurrencyCode VARCHAR(10) NULL, +TransactionType VARCHAR(50) NULL, +PaymentGateway VARCHAR(100) NULL, +CreatedAt DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP, +CompletedAt DATETIME NULL, +Status VARCHAR(50) NULL); + +-- Insert Sample Data (Optional) +INSERT INTO transactions (TransactionId, CustomerId, OrderId, InvoiceNumber, Description, Amount, CurrencyCode, TransactionType, PaymentGateway, CreatedAt, CompletedAt, Status) VALUES +('TXN260113001', 1001, 50001, 'INV-2026-001', 'Samsung S25 Ultra', 153399.00, 'INR', 'SALE', 'Razorpay', '2026-01-13 10:15:30', '2026-01-13 10:16:55', 'SUCCESS'), +('TXN260113002', 1002, 50002, 'INV-2026-002', 'MacBook Pro M4', 224199.00, 'INR', 'SALE', 'Stripe', '2026-01-13 11:20:10', '2026-01-13 11:21:40', 'SUCCESS'); +``` +Upon executing the script, the transaction records will be stored in the transactions table within the transactiondb database. The database is now populated with records and ready for further use. + +### Step 2: Install required NuGet packages -The Syncfusion® Blazor DataGrid component supports binding data from a MySQL Server database using multiple approaches. Common methods include: +Open Visual Studio, navigate to the **Package Manager Console**, and install the necessary packages. -- Using the [DataSource](https://help.syncfusion.com/cr/blazor/Syncfusion.Blazor.Grids.SfGrid-1.html#Syncfusion_Blazor_Grids_SfGrid_1_DataSource) property for local binding. -- Implementing a [CustomAdaptor](https://blazor.syncfusion.com/documentation/datagrid/connecting-to-adaptors/custom-adaptor) for custom logic. -- Configuring remote data binding through adaptors such as [UrlAdaptor](https://blazor.syncfusion.com/documentation/data/adaptors#url-adaptor). +```powershell +Install-Package Microsoft.EntityFrameworkCore -Version 9.0.0 ; +Install-Package Microsoft.EntityFrameworkCore.Tools -Version 9.0.0 ; +Install-Package Pomelo.EntityFrameworkCore.MySql -Version 9.0.0 +``` +Alternatively, use NuGet Package Manager UI: -**Using UrlAdaptor** +1. Open **Visual Studio 2022 → Tools → NuGet Package Manager → Manage NuGet Packages for Solution** +2. Search for and install **Microsoft.EntityFrameworkCore** (version 9.0.0 or later) +3. Search for and install **Microsoft.EntityFrameworkCore.Tools**(version 9.0.0 or later) +4. Search for and install **Pomelo.EntityFrameworkCore.MySql** (version 9.0.0 or later) -The [UrlAdaptor](https://blazor.syncfusion.com/documentation/data/adaptors#url-adaptor) enables communication between the DataGrid and a remote API service connected to **MySQL** Server. This approach is suitable when the API implements custom logic for data operations and returns results in the **result** and **count** format. +The required packages are installed for the server setup. -**Using CustomAdaptor** +### Step 3: Create the data model -The [CustomAdaptor](https://blazor.syncfusion.com/documentation/datagrid/connecting-to-adaptors/custom-adaptor) provides full control over data operations and CRUD functionality. It allows implementing custom logic for **searching**, **filtering**, **sorting**, **paging**, and **grouping** directly in the server-side code. +Create a new **Data** folder in the Blazor application and add a new **Transaction.cs** file. Then define a model class named "TransactionModel" with appropriate properties and data annotations that represents the database entity. -## Binding data from MySQL Server using an API service +```csharp +using System.ComponentModel.DataAnnotations; -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. +namespace Transaction.Data +{ + public class TransactionModel + { + [Key] + public int Id { get; set; } + + public string? TransactionId { get; set; } + public int? CustomerId { get; set; } + public int? OrderId { get; set; } + public string? InvoiceNumber { get; set; } + public string? Description { get; set; } + public decimal Amount { get; set; } + public string? CurrencyCode { get; set; } + public string? TransactionType { get; set; } + public string? PaymentGateway { get; set; } + public DateTime? CreatedAt { get; set; } + public DateTime? CompletedAt { get; set; } + public string? Status { get; set; } + } +} +``` +Model class for the transactions table has been created. -### Creating an API service +### Step 4: Configure the DbContext -1. **Create an ASP.NET Core Web API Project** +The `DbContext` in Entity Framework Core manages database connections and translates application-level operations into MySQL commands. To implement this, create the **Data/TransactionDbContext.cs** file and define the "TransactionDbContext" class, which contains the entity configurations required for the MySQL database. -In Visual Studio, create a new **ASP.NET Core Web API** project named **MyWebService**. +```csharp +using Microsoft.EntityFrameworkCore; -Refer to [Microsoft documentation](https://learn.microsoft.com/en-us/visualstudio/get-started/csharp/tutorial-aspnet-core?view=vs-2022) for detailed steps. +namespace Transaction.Data +{ + /// + /// DbContext for Transaction entity + /// Manages database connections and entity configurations + /// + public class TransactionDbContext : DbContext + { + public TransactionDbContext(DbContextOptions options) + : base(options) + { + } -2. **Install SQL Client Package** + /// + /// DbSet for Transaction entities + /// + public DbSet Transactions => Set(); -Add the [MySQL.Data](https://www.nuget.org/packages/MySql.Data) NuGet package to the project using NuGet Package Manager (*Tools → NuGet Package Manager → Manage NuGet Packages for Solution*). + /// + /// Configures the entity mappings and constraints + /// + protected override void OnModelCreating(ModelBuilder modelBuilder) + { + base.OnModelCreating(modelBuilder); -3. **Add API Controller** + // Configure Transaction entity + modelBuilder.Entity(entity => + { + // Primary Key + entity.HasKey(e => e.Id); -Create a controller named **GridController.cs** under the Controllers folder. + // Auto-increment for Primary Key + entity.Property(e => e.Id) + .ValueGeneratedOnAdd(); -4. **Fetch Data from SQL Server** + // Column configurations + entity.Property(e => e.TransactionId) + .HasMaxLength(50) + .IsRequired(true); -Use **SqlConnection** and **SqlDataAdapter** to retrieve data and convert it into a collection of Order objects: + entity.Property(e => e.InvoiceNumber) + .HasMaxLength(100) + .IsRequired(false); -{% 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; + entity.Property(e => e.Description) + .HasMaxLength(500) + .IsRequired(false); -namespace MyWebService.Controllers + entity.Property(e => e.CurrencyCode) + .HasMaxLength(3) + .HasDefaultValue("INR"); + + entity.Property(e => e.TransactionType) + .HasMaxLength(50) + .IsRequired(false); + + entity.Property(e => e.PaymentGateway) + .HasMaxLength(50) + .IsRequired(false); + + entity.Property(e => e.Status) + .HasMaxLength(50) + .IsRequired(false); + + entity.Property(e => e.Amount) + .HasPrecision(10, 2); + + entity.Property(e => e.CustomerId) + .IsRequired(false); + + entity.Property(e => e.OrderId) + .IsRequired(false); + + entity.Property(e => e.CreatedAt) + .HasColumnType("datetime") + .IsRequired(false); + + entity.Property(e => e.CompletedAt) + .HasColumnType("datetime") + .IsRequired(false); + + entity.ToTable("transactions"); + }); + } + } +} +``` + +### Step 5: Configure the connection string + +The connection string specifies the information that connects the database like MySQL server location, credentials, and database name in the runtime. +Update **appsettings.json** file with MySQL connection string: + +```json { - [ApiController] - public class GridController : ControllerBase + "ConnectionStrings": { + "DefaultConnection": "Server=localhost;Port=3306;Database=transactiondb;Uid=root;Pwd=Amrish_arjun11;SslMode=None;ConvertZeroDateTime=false;" + }, + "Logging": { + "LogLevel": { + "Default": "Information", + "Microsoft.AspNetCore": "Warning" + } + }, + "AllowedHosts": "*" +} +``` + +**Connection String Components:** +- Server: MySQL server address (localhost for local development) +- Port: MySQL port (default is 3306) +- Database: Database name (transactiondb) +- User: MySQL username (root) +- Password: MySQL password + +Now data base connection has been established. + +### Step 6: Create the repository pattern class + +Create a new file named repository class **TransactionRepository.cs** in the **Data** folder and implement a repository class called `TransactionRepository` to handle all data operations using Entity Framework Core. + +```csharp +using Microsoft.EntityFrameworkCore; + +namespace Transaction.Data +{ + /// + /// Repository pattern implementation for Transaction entity using Entity Framework Core + /// Handles all CRUD operations and business logic for transactions + /// + public class TransactionRepository { - public static List Orders { get; set; } + private readonly TransactionDbContext _context; - public class Order + public TransactionRepository(TransactionDbContext context) { - [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; } + _context = context; } - [Route("api/[controller]")] - public List GetOrderData() + /// + /// Retrieves all transactions from the database ordered by ID descending + /// + /// List of all transactions + public async Task> GetTransactionsAsync() { - //TODO: Enter the connectionstring of database - string ConnectionString = @""; - string QueryStr = "SELECT * FROM orders ORDER BY OrderID"; - MySqlConnection sqlConnection = new(ConnectionString); - sqlConnection.Open(); - //Initialize the MySqlCommand - MySqlCommand SqlCommand = new(QueryStr, sqlConnection); - //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 MySqlDataAdapter 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; + return await _context.Transactions + .OrderByDescending(t => t.Id) + .ToListAsync(); } } } -{% endhighlight %} -{% endtabs %} - -5. **Run and test the application** - -Start the API and access **https://localhost:xxxx/api/Grid** to view the data. - -![Hosted API URL](../images/Ms-Sql-data.png) - -### Connecting Blazor DataGrid to an API service +``` -This section explains how to retrieve data from a **MySQL** Server database using `UrlAdaptor` and bind it to the Syncfusion® Blazor DataGrid component. +### Step 7: Register DbContext -**Prerequisites** +Register the TransactionDbContext to manage database connections and provide data access throughout the project. Configure the Entity Framework Core in **Program.cs** file: -* [System requirements for Blazor components](https://blazor.syncfusion.com/documentation/system-requirements) +```csharp +using Microsoft.EntityFrameworkCore; -1. **Create a Blazor Web App** +var builder = WebApplication.CreateBuilder(args); -Create a **Blazor Web App** using Visual Studio 2022. Use [Microsoft Templates](https://learn.microsoft.com/en-us/aspnet/core/blazor/tooling?view=aspnetcore-9.0&pivots=vs) or the Syncfusion® Blazor Extension. +var connectionString = builder.Configuration.GetConnectionString("DefaultConnection"); -> Configure the [Interactive render mode](https://learn.microsoft.com/en-us/aspnet/core/blazor/components/render-modes?view=aspnetcore-9.0#render-modes) and [Interactivity location](https://learn.microsoft.com/en-us/aspnet/core/blazor/tooling?view=aspnetcore-9.0&pivots=vs) during project creation. +builder.Services.AddDbContext(options => +{ + options.UseMySql( + connectionString, + ServerVersion.AutoDetect(connectionString) + ); +}); -2. **Install Syncfusion Packages** +builder.Services.AddScoped(); +``` +Now Services registration has been completed for data access. -* Open the NuGet Package Manager in Visual Studio (*Tools → NuGet Package Manager → Manage NuGet Packages for Solution*). Search and install the following packages: +## Integrating Syncfusion Blazor DataGrid - - [Syncfusion.Blazor.Grid](https://www.nuget.org/packages/Syncfusion.Blazor.Grid/) - - [Syncfusion.Blazor.Themes](https://www.nuget.org/packages/Syncfusion.Blazor.Themes/) +### Step 1: Install required NuGet packages and register Syncfusion services -* Alternatively, use the Package Manager Console: +open Visual Studio, navigate to the **Package Manager Console**, and install the necessary packages. ```powershell -Install-Package Syncfusion.Blazor.Grid -Version {{ site.releaseversion }} -Install-Package Syncfusion.Blazor.Themes -Version {{ site.releaseversion }} +Install-Package Syncfusion.Blazor -Version 28.1.33 ``` +Registers the Syncfusion component services required by the DataGrid at runtime and exposes grid APIs via dependency injection. + +Configure Syncfusion services in **Program.cs**: -> When using **WebAssembly** or **Auto** render modes in a Blazor Web App, install Syncfusion® Blazor component NuGet packages within the client project. +```csharp +using Syncfusion.Blazor; -> Syncfusion® Blazor components are available on [nuget.org](https://www.nuget.org/packages?q=syncfusion.blazor). Refer to the [NuGet packages](https://blazor.syncfusion.com/documentation/nuget-packages) topic for a complete list of available packages. +var builder = WebApplication.CreateBuilder(args); -3. **Register Syncfusion Blazor service** +// Register Syncfusion Blazor services +builder.Services.AddSyncfusionBlazor(); +``` -- Add the required namespaces in **~/_Imports.razor**: +**Import namespaces:** -```cshtml +Add required namespaces in **Components/_Imports.razor**: + +```csharp @using Syncfusion.Blazor @using Syncfusion.Blazor.Grids +@using Syncfusion.Blazor.Data ``` -- For apps using **WebAssembly** or **Auto** (Server and WebAssembly) render modes, register the service in both **~/Program.cs** files. +**Add stylesheet and script resources:** -```cshtml -using Syncfusion.Blazor; - -builder.Services.AddSyncfusionBlazor(); +Add stylesheet and script resources in **Components/App.razor** + +```html + + + + ``` -4. **Add stylesheet and script resources** +**Add Syncfusion Blazor DataGrid component** -Access the theme stylesheet and script from NuGet using [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 **~/Components/App.razor**: +Create new **Home.razor** file and add the Syncfusion® Blazor DataGrid component. The DataGrid automatically generates columns when no explicit column definitions are provided. For greater control over column behavior and appearance, use [GridColumn](https://help.syncfusion.com/cr/blazor/Syncfusion.Blazor.Grids.GridColumn.html) to specify each column and configure properties such as [Field](https://help.syncfusion.com/cr/blazor/Syncfusion.Blazor.Grids.GridColumn.html#Syncfusion_Blazor_Grids_GridColumn_Field), [HeaderText](https://help.syncfusion.com/cr/blazor/Syncfusion.Blazor.Grids.GridColumn.html#Syncfusion_Blazor_Grids_GridColumn_HeaderText) and [Width](https://help.syncfusion.com/cr/blazor/Syncfusion.Blazor.Grids.GridColumn.html#Syncfusion_Blazor_Grids_GridColumn_Width). This approach provides full control over column behavior and appearance. ```html - - - - - - - + + + + + + + + ``` -> * Refer to [Blazor Themes](https://blazor.syncfusion.com/documentation/appearance/themes) for additional methods such as [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). -> * Set the render mode to **InteractiveServer** or **InteractiveAuto** in the Blazor Web App configuration. +> * Set [IsPrimaryKey](https://help.syncfusion.com/cr/blazor/Syncfusion.Blazor.Grids.GridColumn.html#Syncfusion_Blazor_Grids_GridColumn_IsPrimaryKey) to **true** for a column that contains unique values. +> * If the database includes an **auto-generated column**, set [IsIdentity](https://help.syncfusion.com/cr/blazor/Syncfusion.Blazor.Grids.GridColumn.html#Syncfusion_Blazor_Grids_GridColumn_IsIdentity) for that column to disable editing during **add** or **update** operations. -5. **Configure DataGrid with UrlAdaptor** +Service registration and namespace imports have been completed. Continue with configuring DataGrid–SQL Server integration using the CustomAdaptor -The [SfDataManager](https://help.syncfusion.com/cr/blazor/Syncfusion.Blazor.Data.SfDataManager.html) component supports multiple adaptors for remote data binding. For API services, set the [Adaptor](https://help.syncfusion.com/cr/blazor/Syncfusion.Blazor.Adaptors.html) property to [Adaptors.UrlAdaptor](https://help.syncfusion.com/cr/blazor/Syncfusion.Blazor.Adaptors.html#Syncfusion_Blazor_Adaptors_UrlAdaptor) and specify the service endpoint in the [Url](https://help.syncfusion.com/cr/blazor/Syncfusion.Blazor.DataManager.html#Syncfusion_Blazor_DataManager_Url) property. +### Step 2: Bind data from MySQL Server using CustomAdaptor -{% tabs %} -{% highlight razor tabtitle="Index.razor" %} -@using Syncfusion.Blazor.Grids -@using Syncfusion.Blazor.Data -@using Syncfusion.Blazor +The Syncfusion® Blazor DataGrid can bind data from a **MySQL Server** database using [DataManager](https://help.syncfusion.com/cr/blazor/Syncfusion.Blazor.Data.SfDataManager.html) and set the [Adaptor](https://help.syncfusion.com/cr/blazor/Syncfusion.Blazor.Adaptors.html) property to [CustomAdaptor](https://blazor.syncfusion.com/documentation/datagrid/connecting-to-adaptors/custom-adaptor) for scenarios that require full control over data operations. +The CustomAdaptor serves as the bridge between DataGrid UI interactions and MySQL Server database operations. When users interact with the grid (search, filter, sort, page), the adaptor intercepts these requests and executes corresponding MySQL operations. - - - - - - - - - @{ - var aggregate = (context as AggregateTemplateContext); -
-

Sum: @aggregate.Sum

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

Average: @aggregate.Average

-
- } -
-
-
-
-
- - - - - - - -
+### Implement CustomAdaptor -@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; } +Create a CustomAdaptor class in **Components/Pages/Home.razor** that bridges DataGrid actions with MySQL Server operations: + +```csharp +public class CustomAdaptor : DataAdaptor +{ + public static TransactionRepository? _transactionService { get; set; } + public TransactionRepository? TransactionService + { + get => _transactionService; + set => _transactionService = value; } -} -{% 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 + /// ReadAsync - Retrieves records from MySQL Server and applies data operations + /// Executes on grid initialization and when user performs search, filter, sort, page operations /// - /// 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) + public override async Task ReadAsync(DataManagerRequest dataManagerRequest, string? key = null) { - IEnumerable DataSource = GetOrderData(); - int TotalRecordsCount = DataSource.Cast().Count(); - return new { result = DataSource, count = TotalRecordsCount}; - } -} -{% endhighlight %} -{% endtabs %} + // Fetch all records from MySQL Server via data layer + IEnumerable dataSource = await _transactionService!.GetTransactionsAsync(); -### Handling data operations in UrlAdaptor + // Apply data operations (search, filter, sort, aggregate, paging, grouping) as requested + // Detailed implementations for each operation follow in subsequent sections -The Syncfusion® Blazor DataGrid supports server-side operations such as **searching**, **sorting**, **filtering**, **aggregating**, and **paging** when using the [UrlAdaptor](https://blazor.syncfusion.com/documentation/data/adaptors#url-adaptor). + // Calculate total record count for pagination metadata + int totalRecordsCount = dataSource.Cast().Count(); -The [DataManagerRequest](https://help.syncfusion.com/cr/blazor/Syncfusion.Blazor.DataManagerRequest.html) object provides details for each operation, and these can be applied using built-in methods from the [DataOperations](https://help.syncfusion.com/cr/blazor/Syncfusion.Blazor.DataOperations.html) class: + // Return DataResult containing filtered/sorted records and total count + return dataManagerRequest.RequiresCounts + ? new DataResult() { Result = dataSource, Count = totalRecordsCount } + : (object)dataSource; + } +} +``` -* [PerformSearching](https://help.syncfusion.com/cr/blazor/Syncfusion.Blazor.DataOperations.html#Syncfusion_Blazor_DataOperations_PerformSearching__1_System_Linq_IQueryable___0__System_Collections_Generic_List_Syncfusion_Blazor_Data_SearchFilter__) -Applies search criteria to the data source based on search filters. -* [PerformFiltering](https://help.syncfusion.com/cr/blazor/Syncfusion.Blazor.DataOperations.html#Syncfusion_Blazor_DataOperations_PerformFiltering__1_System_Linq_IQueryable___0__System_Collections_Generic_List_Syncfusion_Blazor_Data_WhereFilter__System_String_) - Filters the data source using conditions specified in the request. -* [PerformSorting](https://help.syncfusion.com/cr/blazor/Syncfusion.Blazor.DataOperations.html#Syncfusion_Blazor_DataOperations_PerformSorting__1_System_Linq_IQueryable___0__System_Collections_Generic_List_Syncfusion_Blazor_Data_Sort__) - Sorts the data source according to one or more sort descriptors. -* [PerformTake](https://help.syncfusion.com/cr/blazor/Syncfusion.Blazor.DataOperations.html#Syncfusion_Blazor_DataOperations_PerformTake__1_System_Linq_IQueryable___0__System_Int32_) - Retrieves a specified number of records for paging. -* [PerformSkip](https://help.syncfusion.com/cr/blazor/Syncfusion.Blazor.DataOperations.html#Syncfusion_Blazor_DataOperations_PerformSkip__1_System_Linq_IQueryable___0__System_Int32_) - Skips a defined number of records before returning results. +**CustomAdaptor methods reference**: +- [ReadAsync(DataManagerRequest)](https://help.syncfusion.com/cr/blazor/Syncfusion.Blazor.DataAdaptor.html#Syncfusion_Blazor_DataAdaptor_ReadAsync_Syncfusion_Blazor_DataManagerRequest_System_String_) - Retrieve and process records (search, filter, sort, page, group) +- [InsertAsync(DataManager, object)](https://help.syncfusion.com/cr/blazor/Syncfusion.Blazor.DataAdaptor.html#Syncfusion_Blazor_DataAdaptor_InsertAsync_Syncfusion_Blazor_DataManager_System_Object_System_String_) - Create new records in MySQL Server +- [UpdateAsync(DataManager, object, string, string)](https://help.syncfusion.com/cr/blazor/Syncfusion.Blazor.DataAdaptor.html#Syncfusion_Blazor_DataAdaptor_UpdateAsync_Syncfusion_Blazor_DataManager_System_Object_System_String_System_String_) - Edit existing records in MySQL Server +- [RemoveAsync(DataManager, object, string, string)](https://help.syncfusion.com/cr/blazor/Syncfusion.Blazor.DataAdaptor.html#Syncfusion_Blazor_DataAdaptor_RemoveAsync_Syncfusion_Blazor_DataManager_System_Object_System_String_System_String_) - Delete records from MySQL Server +- [BatchUpdateAsync(DataManager, object, object, object, string, string, int?)](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__) - Handle bulk operations -These methods enable efficient handling of large datasets by performing operations on the server side. The following sections demonstrate how to manage these operations using the `UrlAdaptor`. +Bind the adaptor to the DataGrid markup in **Home.razor**: -> * To enable these operations, add the **Syncfusion.Blazor.Data** package to the API service project using NuGet Package Manager in Visual Studio (*Tools → NuGet Package Manager → Manage NuGet Packages for Solution*). +```html + + + +``` -### Handling searching operation +**Data flow architecture**: -Enable server-side searching by implementing logic in the API controller with 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 method applies search criteria to the collection based on filters specified in the incoming [DataManagerRequest](https://help.syncfusion.com/cr/blazor/Syncfusion.Blazor.DataManagerRequest.html). +![Blazor DataGrid component bound with Microsoft MySQL Server data](../images/blazor-Grid-Ms-SQl-databinding-architecture-Png.png) -{% highlight razor %} +The CustomAdaptor implementation centralizes all database logic, enabling consistent MySQL execution, error handling, and performance optimization across all grid operations. -[HttpPost] -[Route("api/[controller]")] -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 - } - int TotalRecordsCount = DataSource.Cast().Count(); - return new { result = DataSource, count = TotalRecordsCount }; -} -{% endhighlight %} +### Handling data operations -### Handling filtering operation +Server-side data operations optimize performance by processing data before transmission to the client. Each operation in the CustomAdaptor's `ReadAsync` method handles specific grid functionality. The Syncfusion® Blazor DataGrid sends operation details to the API through a [DataManagerRequest](https://help.syncfusion.com/cr/blazor/Syncfusion.Blazor.DataManagerRequest.html) object. These details can be applied to the data source using methods from the [DataOperations](https://help.syncfusion.com/cr/blazor/Syncfusion.Blazor.DataOperations.html) class. -Enable server-side filtering by implementing logic in the API controller using the [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 from the [DataOperations](https://help.syncfusion.com/cr/blazor/Syncfusion.Blazor.DataOperations.html) class. This method applies filter conditions to the collection based on the criteria specified in the incoming [DataManagerRequest](https://help.syncfusion.com/cr/blazor/Syncfusion.Blazor.DataManagerRequest.html). +**Common methods in dataoperations** -{% highlight razor %} -[HttpPost] -[Route("api/[controller]")] -public object Post([FromBody] DataManagerRequest DataManagerRequest) -{ - IEnumerable DataSource = GetOrderData(); - // 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 TotalRecordsCount = DataSource.Cast().Count(); - return new { result = DataSource, count = TotalRecordsCount }; -} +* [PerformSearching](https://help.syncfusion.com/cr/blazor/Syncfusion.Blazor.DataOperations.html#Syncfusion_Blazor_DataOperations_PerformSearching__1_System_Linq_IQueryable___0__System_Collections_Generic_List_Syncfusion_Blazor_Data_SearchFilter__) - Applies search criteria to the collection. +* [PerformFiltering](https://help.syncfusion.com/cr/blazor/Syncfusion.Blazor.DataOperations.html#Syncfusion_Blazor_DataOperations_PerformFiltering__1_System_Linq_IQueryable___0__System_Collections_Generic_List_Syncfusion_Blazor_Data_WhereFilter__System_String_) - Filters data based on conditions. +* [PerformSorting](https://help.syncfusion.com/cr/blazor/Syncfusion.Blazor.DataOperations.html#Syncfusion_Blazor_DataOperations_PerformSorting__1_System_Linq_IQueryable___0__System_Collections_Generic_List_Syncfusion_Blazor_Data_Sort__) - Sorts data by one or more fields. +* [PerformSkip](https://help.syncfusion.com/cr/blazor/Syncfusion.Blazor.DataOperations.html#Syncfusion_Blazor_DataOperations_PerformSkip__1_System_Linq_IQueryable___0__System_Int32_) - Skips a defined number of records for paging. +* [PerformTake](https://help.syncfusion.com/cr/blazor/Syncfusion.Blazor.DataOperations.html#Syncfusion_Blazor_DataOperations_PerformTake__1_System_Linq_IQueryable___0__System_Int32_) - Retrieves a specified number of records for paging. +* [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__) – Calculates aggregate values such as Sum, Average, Min, and Max. -{% endhighlight %} +--- -### Handling sorting operation +### Searching -Enable server-side sorting by implementing logic in the API controller 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 method sorts the collection based on one or more sort descriptors specified in the incoming [DataManagerRequest](https://help.syncfusion.com/cr/blazor/Syncfusion.Blazor.DataManagerRequest.html). +Enables keyword-based query across configured fields, allowing the grid to delegate search criteria to the adaptor for efficient server-side filtering. The built-in `PerformSearching` method of the `DataOperations` class applies search criteria from the `DataManagerRequest` to the data source. -{% highlight razor %} -[HttpPost] -[Route("api/[controller]")] -public object Post([FromBody] DataManagerRequest DataManagerRequest) +```csharp +public class CustomAdaptor : DataAdaptor { - IEnumerable DataSource = GetOrderData(); - // Handling Sorting in UrlAdaptor. - if (DataManagerRequest.Sorted != null && DataManagerRequest.Sorted.Count > 0) + public override async Task ReadAsync(DataManagerRequest dataManagerRequest, string? key = null) { - // Sorting - DataSource = DataOperations.PerformSorting(DataSource, DataManagerRequest.Sorted); - //Add custom logic here if needed and remove above method + IEnumerable dataSource = await _transactionService!.GetTransactionsAsync(); + + // Handling Searching + if (dataManagerRequest.Search != null && dataManagerRequest.Search.Count > 0) + { + dataSource = DataOperations.PerformSearching(dataSource, dataManagerRequest.Search); + } + + return dataManagerRequest.RequiresCounts + ? new DataResult() { Result = dataSource, Count = totalRecordsCount } + : (object)dataSource; } - int TotalRecordsCount = DataSource.Cast().Count(); - return new { result = DataSource, count = TotalRecordsCount }; } -{% endhighlight %} - -### Handling aggregate operation - -Enable server-side aggregation by implementing logic in the API controller 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 method calculates aggregate values such as **Sum**, **Average**, **Min**, and **Max** for the specified fields based on the incoming [DataManagerRequest](https://help.syncfusion.com/cr/blazor/Syncfusion.Blazor.DataManagerRequest.html). - -{% highlight razor %} - [HttpPost] - [Route("api/[controller]")] - public object Post([FromBody] DataManagerRequest DataManagerRequest) - { - IEnumerable DataSource = GetOrderData(); - int TotalRecordsCount = 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 - } - return new { result = DataSource, count = TotalRecordsCount, aggregates = Aggregates }; - } -{% endhighlight %} +``` -> The server-side implementation of the `PerformAggregation` method is required only for [Footer aggregates](https://blazor.syncfusion.com/documentation/datagrid/footer-aggregate). Explicit handling is not necessary for[ Group Footer aggregates](https://blazor.syncfusion.com/documentation/datagrid/group-and-caption-aggregate#group-footer-aggregates) or [Group Caption aggregates](https://blazor.syncfusion.com/documentation/datagrid/group-and-caption-aggregate#group-caption-aggregates). +To enable Searching add the Search item to the toolbar using the [Toolbar](https://help.syncfusion.com/cr/blazor/Syncfusion.Blazor.Grids.SfGrid-1.html#Syncfusion_Blazor_Grids_SfGrid_1_Toolbar) property in the DataGrid markup: + +```html + + + + +``` +--- -### Handling paging operation +### Filtering -Enable server-side paging by implementing logic in the API controller using the [PerformSkip](https://help.syncfusion.com/cr/blazor/Syncfusion.Blazor.DataOperations.html#Syncfusion_Blazor_DataOperations_PerformSkip__1_System_Collections_Generic_IEnumerable___0__System_Int32_) and [PerformTake](https://help.syncfusion.com/cr/blazor/Syncfusion.Blazor.DataOperations.html#Syncfusion_Blazor_DataOperations_PerformTake__1_System_Collections_Generic_IEnumerable___0__System_Int32_) methods from the [DataOperations](https://help.syncfusion.com/cr/blazor/Syncfusion.Blazor.DataOperations.html) class. These methods apply paging based on the **Skip** and **Take** values provided in the incoming [DataManagerRequest](https://help.syncfusion.com/cr/blazor/Syncfusion.Blazor.DataManagerRequest.html). +Provides column-level criteria evaluation so the adaptor can restrict datasets at the source for precise, efficient retrieval. The built-in `PerformFiltering` method in the `DataOperations` class applies filter criteria from the `DataManagerRequest` to the data collection. -{% highlight razor %} -[HttpPost] -[Route("api/[controller]")] -public object Post([FromBody] DataManagerRequest DataManagerRequest) +```csharp +public class CustomAdaptor : DataAdaptor { - IEnumerable DataSource = GetOrderData(); - int TotalRecordsCount = DataSource.Cast().Count(); - // 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) + public override async Task ReadAsync(DataManagerRequest dataManagerRequest, string? key = null) { - DataSource = DataOperations.PerformTake(DataSource, DataManagerRequest.Take); - //Add custom logic here if needed and remove above method + IEnumerable dataSource = await _transactionService!.GetTransactionsAsync(); + + // Handling Searching + if (dataManagerRequest.Search != null && dataManagerRequest.Search.Count > 0) + { + dataSource = DataOperations.PerformSearching(dataSource, dataManagerRequest.Search); + } + + // Handling Filtering + if (dataManagerRequest.Where != null && dataManagerRequest.Where.Count > 0) + { + dataSource = DataOperations.PerformFiltering(dataSource, dataManagerRequest.Where, dataManagerRequest.Where[0].Operator); + } + + return dataManagerRequest.RequiresCounts + ? new DataResult() { Result = dataSource, Count = totalRecordsCount } + : (object)dataSource; } - return new { result = DataSource, count = TotalRecordsCount }; } -{% endhighlight %} - -N> For optimal performance, apply operations in the following sequence: **Searching → Filtering → Sorting → Aggregation → Paging → Grouping** in [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 filtering in the DataGrid markup, set the [AllowFiltering](https://help.syncfusion.com/cr/blazor/Syncfusion.Blazor.Grids.SfGrid-1.html#Syncfusion_Blazor_Grids_SfGrid_1_AllowFiltering) property to "true". Configure filtering behavior and appearance using the [GridFilterSettings](https://help.syncfusion.com/cr/blazor/Syncfusion.Blazor.Grids.SfGrid-1.html#Syncfusion_Blazor_Grids_SfGrid_1_AllowFiltering). -The Syncfusion® Blazor DataGrid supports Create, Read, Update, and Delete (CRUD) operations through the [SfDataManager](https://help.syncfusion.com/cr/blazor/Syncfusion.Blazor.Data.SfDataManager.html) component. These operations are mapped to API endpoints using properties such as: +```html + + + + + +``` +--- -* [InsertUrl](https://help.syncfusion.com/cr/blazor/Syncfusion.Blazor.DataManager.html#Syncfusion_Blazor_DataManager_InsertUrl) – API endpoint for inserting new records. -* [UpdateUrl](https://help.syncfusion.com/cr/blazor/Syncfusion.Blazor.DataManager.html#Syncfusion_Blazor_DataManager_UpdateUrl) – API endpoint for updating existing records. -* [RemoveUrl](https://help.syncfusion.com/cr/blazor/Syncfusion.Blazor.DataManager.html#Syncfusion_Blazor_DataManager_UpdateUrl) – API endpoint for deleting records. -* [CrudUrl](https://help.syncfusion.com/cr/blazor/Syncfusion.Blazor.DataManager.html#Syncfusion_Blazor_DataManager_CrudUrl) – Single endpoint for all CRUD operations. -* [BatchUrl](https://help.syncfusion.com/cr/blazor/Syncfusion.Blazor.DataManager.html#Syncfusion_Blazor_DataManager_BatchUrl) – API endpoint for batch editing. +### Sorting -To enable editing, configure the [Toolbar](https://help.syncfusion.com/cr/blazor/Syncfusion.Blazor.Grids.SfGrid-1.html#Syncfusion_Blazor_Grids_SfGrid_1_Toolbar) and [GridEditSettings](https://help.syncfusion.com/cr/blazor/Syncfusion.Blazor.Grids.GridEditSettings.html) properties, and set the Mode property to [EditMode.Normal](https://help.syncfusion.com/cr/blazor/Syncfusion.Blazor.Grids.EditMode.html#Syncfusion_Blazor_Grids_EditMode_Normal) to allow adding, editing, and deleting records. +Enables deterministic record ordering by delegating sort descriptors to the adaptor for database-optimized sorting. The built-in `PerformSorting` method in the `DataOperations` class applies sort criteria from the `DataManagerRequest` to the data collection. -{% tabs %} -{% highlight razor %} - - - - - - - - - - - -{% endhighlight %} -{% endtabs %} - -> * Normal(Inline) editing is the default [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, set the [IsPrimaryKey](https://help.syncfusion.com/cr/blazor/Syncfusion.Blazor.Grids.GridColumn.html#Syncfusion_Blazor_Grids_GridColumn_IsPrimaryKey) property to **true** for a column that contains unique values. -> * If the database includes an auto-generated column, set the [IsIdentity](https://help.syncfusion.com/cr/blazor/Syncfusion.Blazor.Grids.GridColumn.html#Syncfusion_Blazor_Grids_GridColumn_IsIdentity) property for that column to disable editing during **add** or **update** operations. - -**Insert Operation:** - -To insert a new record, click the **Add** toolbar button. This action displays the edit form for entering the new record details. After providing the required values, click the **Update** toolbar button. The record will be added to the Orders table by invoking the following **POST** API method. - -{% 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, select the required row and click the **Edit** button in the toolbar. An edit form will appear, allowing changes to any column value. After making the changes, click the **Update** button in the toolbar to save the record in the Orders table. This action triggers the following **POST** method in the 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 remove a record, select the desired row and click the **Delete** toolbar button. This action sends a **DELETE** request to the configured API endpoint, passing the primary key of the selected record. The corresponding entry will be deleted from the Orders table by invoking the following **POST** API method. - -{% 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 updates, set the edit [Mode](https://help.syncfusion.com/cr/blazor/Syncfusion.Blazor.Grids.GridEditSettings.html#Syncfusion_Blazor_Grids_GridEditSettings_Mode) to **Batch** in the [GridEditSettings](https://help.syncfusion.com/cr/blazor/Syncfusion.Blazor.Grids.GridEditSettings.html) component and configure the [BatchUrl](https://help.syncfusion.com/cr/blazor/Syncfusion.Blazor.DataManager.html#Syncfusion_Blazor_DataManager_BatchUrl) property in the [DataManager](https://help.syncfusion.com/cr/blazor/Syncfusion.Blazor.Data.SfDataManager.html). -In batch mode: - -- Use the **Add** toolbar button to insert new rows. -- Double-click a cell to edit its value. -- Select a row and click **Delete** to remove it. -- Click **Update** to commit all changes (insert, update, delete) in a single request from the Orders table using a single API **POST** request. - -{% highlight razor %} - [HttpPost] -[Route("api/Grid/Batch")] -/// -/// 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 -public void Batch([FromBody] CRUDModel Value) +```csharp +public class CustomAdaptor : DataAdaptor { - //TODO: Enter the connectionstring of database - string ConnectionString = @""; - if (Value.Changed != null) + public override async Task ReadAsync(DataManagerRequest dataManagerRequest, string? key = null) { - foreach (var Record in (IEnumerable)Value.Changed) + IEnumerable dataSource = await _transactionService!.GetTransactionsAsync(); + + // Handling Searching + if (dataManagerRequest.Search != null && dataManagerRequest.Search.Count > 0) { - //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 + dataSource = DataOperations.PerformSearching(dataSource, dataManagerRequest.Search); } - } - if (Value.Added != null) - { - foreach (var Record in (IEnumerable)Value.Added) + // Handling Filtering + if (dataManagerRequest.Where != null && dataManagerRequest.Where.Count > 0) { - //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 + dataSource = DataOperations.PerformFiltering(dataSource, dataManagerRequest.Where, dataManagerRequest.Where[0].Operator); } - } - if (Value.Deleted != null) - { - foreach (var Record in (IEnumerable)Value.Deleted) + + // Handling Sorting + if (dataManagerRequest.Sorted != null && dataManagerRequest.Sorted.Count > 0) { - //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 + dataSource = DataOperations.PerformSorting(dataSource, dataManagerRequest.Sorted); } - } -} -{% endhighlight %} -![Blazor DataGrid component bound with MySQL Server data](../images/blazor-Grid-Ms-SQl-databinding-Gif.gif) - -> Find the complete implementation in this [GitHub](https://github.com/SyncfusionExamples/connecting-databases-to-blazor-datagrid-component/tree/master/Binding%20MS%20SQL%20database%20using%20UrlAdaptor) repository. - -## Binding data from MySQL Server using CustomAdaptor - -This section explains how to retrieve data from a Microsoft SQL Server database using [CustomAdaptor](https://blazor.syncfusion.com/documentation/datagrid/connecting-to-adaptors/custom-adaptor) and bind it to the Blazor DataGrid component. - -**Step 1: Create the Blazor DataGrid Component** + return dataManagerRequest.RequiresCounts + ? new DataResult() { Result = dataSource, Count = totalRecordsCount } + : (object)dataSource; + } +} +``` +To enable sorting in the DataGrid markup, set the [AllowSorting](https://help.syncfusion.com/cr/blazor/Syncfusion.Blazor.Grids.SfGrid-1.html#Syncfusion_Blazor_Grids_SfGrid_1_AllowSorting) property to "true". Configure initial sorting by setting the [Field](https://help.syncfusion.com/cr/blazor/Syncfusion.Blazor.Grids.GridSortColumn.html#Syncfusion_Blazor_Grids_GridSortColumn_Field) (the column's data field name) and [Direction](https://help.syncfusion.com/cr/blazor/Syncfusion.Blazor.Grids.GridSortColumn.html#Syncfusion_Blazor_Grids_GridSortColumn_Field) properties in the [Columns](https://help.syncfusion.com/cr/blazor/Syncfusion.Blazor.Grids.GridSortSettings.html#Syncfusion_Blazor_Grids_GridSortSettings_Columns) collection of [GridSortSettings](https://help.syncfusion.com/cr/blazor/Syncfusion.Blazor.Grids.GridSortSettings.html). + -Follow the procedure described in [Connecting Blazor DataGrid to an API service](#connecting-blazor-datagrid-to-an-api-service). +```html + + + + + + + + + + +``` +--- -> * Set the rendermode to **InteractiveServer** or **InteractiveAuto** based on application configuration. +### Aggregation -**Step 2: Install MySQL NuGet Package** +Aggregate functions compute summary statistics across datasets without requiring row-level retrieval, enabling efficient calculation of totals, averages, counts, etc. at the database server level. The built-in `PerformAggregation` method in the [DataUtil](https://help.syncfusion.com/cr/blazor/Syncfusion.Blazor.Data.DataUtil.html) class calculates aggregate values based on the criteria specified in the `DataManagerRequest`. -Install the **MySql.Data** package to connect to MySQL Server. +```csharp +public class CustomAdaptor : DataAdaptor +{ + public override async Task ReadAsync(DataManagerRequest dataManagerRequest, string? key = null) + { + IEnumerable dataSource = await _transactionService!.GetTransactionsAsync(); -In Visual Studio, open (*Tools → NuGet Package Manager → Manage NuGet Packages*) for Solution, search for **MySql.Data**, and install it. + // Handling Searching + if (dataManagerRequest.Search != null && dataManagerRequest.Search.Count > 0) + { + dataSource = DataOperations.PerformSearching(dataSource, dataManagerRequest.Search); + } -**Step 3: Configure the DataGrid with CustomAdaptor** + // Handling Filtering + if (dataManagerRequest.Where != null && dataManagerRequest.Where.Count > 0) + { + dataSource = DataOperations.PerformFiltering(dataSource, dataManagerRequest.Where, dataManagerRequest.Where[0].Operator); + } -Inject a custom service into the `CustomAdaptor` and configure the component as shown below: + // Handling Sorting + if (dataManagerRequest.Sorted != null && dataManagerRequest.Sorted.Count > 0) + { + dataSource = DataOperations.PerformSorting(dataSource, dataManagerRequest.Sorted); + } -{% tabs %} -{% highlight razor tabtitle="Index.razor" %} -@rendermode InteractiveServer + // Handling Aggregation + IDictionary? aggregates = null; + if (dataManagerRequest.Aggregates != null) + { + aggregates = DataUtil.PerformAggregation(dataSource, dataManagerRequest.Aggregates); + } -@using Syncfusion.Blazor.Grids -@using Syncfusion.Blazor.Data -@using Syncfusion.Blazor -@using MySql.Data.MySqlClient; + return dataManagerRequest.RequiresCounts + ? new DataResult() { Result = dataSource, Count = totalRecordsCount } + : (object)dataSource; + } +} +``` +Enable aggregates by including [GridAggregateColumn](https://help.syncfusion.com/cr/blazor/Syncfusion.Blazor.Grids.GridAggregateColumn.html) component in DataGrid markup, for each aggregate column, specify at least the [Field](https://help.syncfusion.com/cr/blazor/Syncfusion.Blazor.Grids.GridAggregateColumn.html#Syncfusion_Blazor_Grids_GridAggregateColumn_Field) and [Type](https://help.syncfusion.com/cr/blazor/Syncfusion.Blazor.Grids.GridAggregateColumn.html#Syncfusion_Blazor_Grids_GridAggregateColumn_Field) properties. - +```html + - + + + + + + + - - - @{ - 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 %} - -**Step 4: Implement Data Retrieval Logic** - -Implement the [ReadAsync](https://help.syncfusion.com/cr/blazor/Syncfusion.Blazor.DataAdaptor.html#Syncfusion_Blazor_DataAdaptor_ReadAsync_Syncfusion_Blazor_DataManagerRequest_System_String_) method in `CustomAdaptor` to fetch data from the service by calling **GetOrdersAsync**. - -* Use `SqlDataAdapter` to retrieve data from Microsoft SQL Server. -* Populate a **DataSet** using the **Fill** method and convert it into a List. -* Return the response as a **Result** and **Count** pair in the `ReadAsync` method to bind data to the Blazor DataGrid. - -{% 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 +### Paging - - - - - - - - - @{ - var aggregate = (context as AggregateTemplateContext); -
-

Sum: @aggregate.Sum

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

Average: @aggregate.Average

-
- } -
-
-
-
-
- - - - - - - -
+Paging divides large result sets into fixed-size pages, reducing memory consumption and improving client-side responsiveness by retrieving only the requested page from the server. The built-in `PerformSkip`, `PerformTake` methods in the `DataOperations` class apply paging criteria from the `DataManagerRequest` to the data collection. -@code { - /// - /// 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 +```csharp +public class CustomAdaptor : DataAdaptor +{ + public override async Task ReadAsync(DataManagerRequest dataManagerRequest, string? key = null) { - 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 _transactionService!.GetTransactionsAsync(); + + // Handling Searching + if (dataManagerRequest.Search != null && dataManagerRequest.Search.Count > 0) { - IEnumerable DataSource = await OrderService.GetOrdersAsync(); - int TotalRecordsCount = DataSource.Cast().Count(); - return DataManagerRequest.RequiresCounts ? new DataResult() { Result = DataSource, Count = TotalRecordsCount } : (object)DataSource; + dataSource = DataOperations.PerformSearching(dataSource, dataManagerRequest.Search); } - } -} -{% endhighlight %} -{% highlight razor tabtitle="OrderData.cs" %} -public class OrderData -{ - public async Task> GetOrdersAsync() + + // Handling Filtering + if (dataManagerRequest.Where != null && dataManagerRequest.Where.Count > 0) { - //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 MySqlDataAdapter 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; + dataSource = DataOperations.PerformFiltering(dataSource, dataManagerRequest.Where, dataManagerRequest.Where[0].Operator); } -} -{% endhighlight %} -{% endtabs %} -![Blazor DataGrid component bound with MySQL Server data](../images/blazor-Grid-Ms-SQL-databinding.png) + // Handling Sorting + if (dataManagerRequest.Sorted != null && dataManagerRequest.Sorted.Count > 0) + { + dataSource = DataOperations.PerformSorting(dataSource, dataManagerRequest.Sorted); + } -### Handling data operations in a Custom Adaptor + // Handling Aggregation + IDictionary? aggregates = null; + if (dataManagerRequest.Aggregates != null) + { + aggregates = DataUtil.PerformAggregation(dataSource, dataManagerRequest.Aggregates); + } -The Syncfusion® Blazor DataGrid supports server-side operations such as **searching**, **filtering**, **sorting**, **paging**, and **aggregating** when using a `CustomAdaptor`. These operations are implemented by 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. + int totalRecordsCount = dataSource.Cast().Count(); -The [DataManagerRequest](https://help.syncfusion.com/cr/blazor/Syncfusion.Blazor.DataManagerRequest.html) object provides the necessary details for each operation, and these can be applied using built-in methods from the [DataOperations](https://help.syncfusion.com/cr/blazor/Syncfusion.Blazor.DataOperations.html) and [DataUtil](https://help.syncfusion.com/cr/blazor/Syncfusion.Blazor.Data.DataUtil.html) classes: + // Handling Paging + if (dataManagerRequest.Skip != 0) + { + dataSource = DataOperations.PerformSkip(dataSource, dataManagerRequest.Skip); + //Add custom logic here if needed and remove above method + } -* [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__) – Applies search criteria to the data source based on search filters. + if (dataManagerRequest.Take != 0) + { + dataSource = DataOperations.PerformTake(dataSource, dataManagerRequest.Take); + //Add custom logic here if needed and remove above method + } -* [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_) – Filters the data source using conditions specified in the request. + return dataManagerRequest.RequiresCounts + ? new DataResult() { Result = dataSource, Count = totalRecordsCount } + : (object)dataSource; + } +} +``` +To enable paging in the DataGrid markup, set the [AllowPaging](https://help.syncfusion.com/cr/blazor/Syncfusion.Blazor.Grids.SfGrid-1.html#Syncfusion_Blazor_Grids_SfGrid_1_AllowPaging) property to "true". Paging options can be configured through the [GridPageSettings](https://help.syncfusion.com/cr/blazor/Syncfusion.Blazor.Grids.SfGrid-1.html#Syncfusion_Blazor_Grids_SfGrid_1_AllowPaging). -* [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_SortedColumn__) – Sorts the data source according to one or more sort descriptors. +```html + + + + + + + + + + + + + + + + + + +``` +--- -* [PerformSkip](https://help.syncfusion.com/cr/blazor/Syncfusion.Blazor.DataOperations.html#Syncfusion_Blazor_DataOperations_PerformSkip__1_System_Collections_Generic_IEnumerable___0__System_Int32_) – Retrieves a specified number of records for paging. +### Grouping -* [PerformTake](https://help.syncfusion.com/cr/blazor/Syncfusion.Blazor.DataOperations.html#Syncfusion_Blazor_DataOperations_PerformTake__1_System_Collections_Generic_IEnumerable___0__System_Int32_) – Skips a defined number of records before returning results. +Grouping hierarchically organizes records by specified column values, enabling data summarization and nested record visualization while reducing query complexity through server-side grouping operations. The built-in `Group` method in the `DataUtil` class applies grouping logic based on the configuration in the `DataManagerRequest`. -* [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__) – Applies aggregate details to calculate summary values such as Sum, Average, Min, and Max. +```csharp +public class CustomAdaptor : DataAdaptor +{ + public override async Task ReadAsync(DataManagerRequest dataManagerRequest, string? key = null) + { + IEnumerable dataSource = await _transactionService!.GetTransactionsAsync(); -These methods enable efficient server-side data handling in a custom adaptor implementation for **MySQL Server**. + // Handling Searching + if (dataManagerRequest.Search != null && dataManagerRequest.Search.Count > 0) + { + dataSource = DataOperations.PerformSearching(dataSource, dataManagerRequest.Search); + } -N> To enable these operations, install the **Syncfusion.Blazor.Data** package using NuGet Package Manager in Visual Studio: + // Handling Filtering + if (dataManagerRequest.Where != null && dataManagerRequest.Where.Count > 0) + { + dataSource = DataOperations.PerformFiltering(dataSource, dataManagerRequest.Where, dataManagerRequest.Where[0].Operator); + } -(*Tools → NuGet Package Manager → Manage NuGet Packages for Solution*). + // Handling Sorting + if (dataManagerRequest.Sorted != null && dataManagerRequest.Sorted.Count > 0) + { + dataSource = DataOperations.PerformSorting(dataSource, dataManagerRequest.Sorted); + } -### Handling searching operation + // Handling Aggregation + IDictionary? aggregates = null; + if (dataManagerRequest.Aggregates != null) + { + aggregates = DataUtil.PerformAggregation(dataSource, dataManagerRequest.Aggregates); + } -When using `CustomAdaptor`, the searching operation is implemented by 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. + int totalRecordsCount = dataSource.Cast().Count(); -The built-in [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 of the [DataOperations](https://help.syncfusion.com/cr/blazor/Syncfusion.Blazor.DataOperations.html) class applies search criteria from the [DataManagerRequest](https://help.syncfusion.com/cr/blazor/Syncfusion.Blazor.DataManagerRequest.html) to the data source. Custom logic can also be implemented to handle searching as required. + // Handling Paging + if (dataManagerRequest.Skip != 0) + { + dataSource = DataOperations.PerformSkip(dataSource, dataManagerRequest.Skip); + //Add custom logic here if needed and remove above method + } -{% 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 CustomAdaptor. - if (DataManagerRequest.Search != null && DataManagerRequest.Search.Count > 0) + if (dataManagerRequest.Take != 0) { - // Searching - DataSource = DataOperations.PerformSearching(DataSource, DataManagerRequest.Search); + dataSource = DataOperations.PerformTake(dataSource, dataManagerRequest.Take); //Add custom logic here if needed and remove above method } - int TotalRecordsCount = DataSource.Cast().Count(); - return DataManagerRequest.RequiresCounts ? new DataResult() { Result = DataSource, Count = TotalRecordsCount } : (object)DataSource; + + DataResult dataObject = new DataResult(); + // Handling Grouping + if (dataManagerRequest.Group != null) + { + IEnumerable ResultData = dataSource.ToList(); + 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 = totalRecordsCount; + dataObject.Aggregates = aggregates; + return dataManagerRequest.RequiresCounts ? dataObject : (object)ResultData; + } + + return dataManagerRequest.RequiresCounts + ? new DataResult() { Result = dataSource, Count = totalRecordsCount } + : (object)dataSource; } } -{% endhighlight %} +``` +To enable grouping in the DataGrid markup, set the [AllowGrouping](https://help.syncfusion.com/cr/blazor/Syncfusion.Blazor.Grids.SfGrid-1.html#Syncfusion_Blazor_Grids_SfGrid_1_AllowGrouping) property to "true". Configure grouping behavior using [GridGroupSettings](https://help.syncfusion.com/cr/blazor/Syncfusion.Blazor.Grids.SfGrid-1.html#Syncfusion_Blazor_Grids_SfGrid_1_GroupSettings). + +```html + + + + + + + + + + + + + + + + + + + +``` -### Handling filtering operation +### Perform CRUD operations -When implementing `CustomAdaptor`, the filtering operation is managed by 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. +CustomAdaptor methods enable users to create, read, update, and delete records directly from the DataGrid. Each operation calls corresponding data layer methods in TransactionRepository.cs to execute MySQL commands. -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 in the [DataOperations](https://help.syncfusion.com/cr/blazor/Syncfusion.Blazor.DataOperations.html) class applies filter criteria from the [DataManagerRequest](https://help.syncfusion.com/cr/blazor/Syncfusion.Blazor.DataManagerRequest.html) to the data collection. Custom filtering logic can also be implemented to meet specific requirements. +**Insert** -{% highlight razor %} +Record insertion enables users to create new transactions directly from the DataGrid interface; the adaptor intercepts the insertion request, applies business logic validation, and persists the new record to the MySQL Server database. + +In **Home.razor** implement `InsertAsync` to handle new record creation: + +```csharp public class CustomAdaptor : DataAdaptor { - public OrderData OrderService = new OrderData(); - // Performs data read operation - public override async Task ReadAsync(DataManagerRequest DataManagerRequest, string Key = null) + public override async Task InsertAsync(DataManager dataManager, object value, string key) { - IEnumerable DataSource = await OrderService.GetOrdersAsync(); - // Handling Filtering in CustomAdaptor. - if (DataManagerRequest.Where != null && DataManagerRequest.Where.Count > 0) + if (value is TransactionModel transaction) { - // Filtering - DataSource = DataOperations.PerformFiltering(DataSource, DataManagerRequest.Where, DataManagerRequest.Where[0].Operator); - //Add custom logic here if needed and remove above method + // This method will be invoked when inserting new records into the Blazor DataGrid component. + await _transactionService!.AddTransactionAsync(transaction); } - int TotalRecordsCount = DataSource.Cast().Count(); - return DataManagerRequest.RequiresCounts ? new DataResult() { Result = DataSource, Count = TotalRecordsCount } : (object)DataSource; + return value; } } -{% endhighlight %} +``` +In **Data/TransactionRepository.cs**, implement the insert method: -### Handling sorting operation +```csharp +public async Task AddTransactionAsync(TransactionModel value) +{ + // Add the transaction to the context + _context.Transactions.Add(value); -When implementing `CustomAdaptor`, the sorting operation is handled by 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. + // Save changes to database + await _context.SaveChangesAsync(); +} +``` +Now the new transaction is persisted to the database and reflected in the grid. -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 in the [DataOperations](https://help.syncfusion.com/cr/blazor/Syncfusion.Blazor.DataOperations.html) class applies sort criteria from the [DataManagerRequest](https://help.syncfusion.com/cr/blazor/Syncfusion.Blazor.DataManagerRequest.html) to the data collection. Custom sorting logic can also be implemented to meet specific requirements. +**Read** -{% 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 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 TotalRecordsCount = DataSource.Cast().Count(); - return DataManagerRequest.RequiresCounts ? new DataResult() { Result = DataSource, Count = TotalRecordsCount } : (object)DataSource; - } -} -{% endhighlight %} +Record retrieval executes MySQL queries against the database and materializes results into the strongly typed Transactions model; the adaptor processes data operations (search, filter, sort, aggregate, page, group) before returning the result set to the grid for display. -### Handling aggregate operation +The `ReadAsync` method is implemented in [Step 02](#step-2-bind-data-from-mysql-server-using-customadaptor), retrieving and processing records from MySQL Server which returns either the IEnumerable result or a `DataResult` object with `Result` and `Count`. -When implementing `CustomAdaptor`, aggregate operations are managed by 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-1.html) abstract class. +Now the grid displays SQL Server data with full support for searching, filtering, sorting, paging, grouping, and aggregation. -The built-in [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 in the [DataUtil](https://help.syncfusion.com/cr/blazor/Syncfusion.Blazor.Data.DataUtil.html) class calculates aggregate values based on the criteria specified in the [DataManagerRequest](https://help.syncfusion.com/cr/blazor/Syncfusion.Blazor.DataManagerRequest.html). Custom aggregation logic can also be implemented when specific requirements exist. +**Update** -{% highlight razor %} +Record modification enables users to edit transaction attributes directly within the DataGrid; the adaptor captures the edited row, validates changes, and synchronizes modifications to the MySQL Server database while maintaining data integrity. + +In **Home.razor** implement `UpdateAsync` to handle record modifications: + +```csharp public class CustomAdaptor : DataAdaptor { - public OrderData OrderService = new OrderData(); - // Performs data read operation - public override async Task ReadAsync(DataManagerRequest DataManagerRequest, string Key = null) + public override async Task UpdateAsync(DataManager dataManager, object value, string keyField, string key) { - IEnumerable DataSource = await OrderService.GetOrdersAsync(); - int TotalRecordsCount = DataSource.Cast().Count(); - // Handling Aggregation in CustomAdaptor. - IDictionary Aggregates = null; - if (DataManagerRequest.Aggregates != null) // Aggregation + if (value is TransactionModel transaction) { - Aggregates = DataUtil.PerformAggregation(DataSource, DataManagerRequest.Aggregates); - //Add custom logic here if needed and remove above method + // This method will be invoked when updating existing records in the Blazor DataGrid component. + await _transactionService!.UpdateTransactionAsync(transaction); } - return DataManagerRequest.RequiresCounts ? new DataResult() { Result = DataSource, Count = TotalRecordsCount, Aggregates = Aggregates } : (object)DataSource; + return value; } } -{% endhighlight %} +``` +In **Data/TransactionRepository.cs**, implement the update method: -> The server-side implementation of the `PerformAggregation` method is required only for [Footer aggregates](https://blazor.syncfusion.com/documentation/datagrid/footer-aggregate). Explicit handling is not necessary for[ Group Footer aggregates](https://blazor.syncfusion.com/documentation/datagrid/group-and-caption-aggregate#group-footer-aggregates) or [Group Caption aggregates](https://blazor.syncfusion.com/documentation/datagrid/group-and-caption-aggregate#group-caption-aggregates). +```csharp +public async Task UpdateTransactionAsync(TransactionModel value) +{ + // Check if transaction exists + var existingTransaction = await _context.Transactions.FindAsync(value.Id); + if (existingTransaction == null) + throw new KeyNotFoundException($"Transaction with ID {value.Id} not found"); + + // Update the entity + _context.Transactions.Update(value); + await _context.SaveChangesAsync(); +} +``` +Now modifications are synchronized to the database and reflected in the grid UI. -### Handling paging operation +**Delete** -When implementing `CustomAdaptor`, paging is managed by 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. +Record deletion enables users to remove transactions directly from the DataGrid; the adaptor intercepts the deletion request, executes corresponding MySQL DELETE statements, and removes the record from both the database and grid display. -The built-in [PerformSkip](https://help.syncfusion.com/cr/blazor/Syncfusion.Blazor.DataOperations.html#Syncfusion_Blazor_DataOperations_PerformSkip__1_System_Collections_Generic_IEnumerable___0__System_Int32_) and [PerformTake](https://help.syncfusion.com/cr/blazor/Syncfusion.Blazor.DataOperations.html#Syncfusion_Blazor_DataOperations_PerformTake__1_System_Collections_Generic_IEnumerable___0__System_Int32_) methods in the [DataOperations](https://help.syncfusion.com/cr/blazor/Syncfusion.Blazor.DataOperations.html) class apply paging criteria from the [DataManagerRequest](https://help.syncfusion.com/cr/blazor/Syncfusion.Blazor.DataManagerRequest.html) to the data collection. Custom paging logic can also be implemented when specific requirements exist. +In **Home.razor** implement `InsertAsync` to handle record deletion: -{% highlight razor %} +```csharp public class CustomAdaptor : DataAdaptor { - public OrderData OrderService = new OrderData(); - // Performs data read operation - public override async Task ReadAsync(DataManagerRequest DataManagerRequest, string Key = null) + public override async Task RemoveAsync(DataManager dataManager, object value, string keyField, string key) { - IEnumerable DataSource = await OrderService.GetOrdersAsync(); - int TotalRecordsCount = DataSource.Cast().Count(); - // Handling paging in CustomAdaptor. - if (DataManagerRequest.Skip != 0) + // This method will be invoked when deleting existing records from the Blazor DataGrid component. + int? recordId = null; + if (value is int intValue) { - // Paging - DataSource = DataOperations.PerformSkip(DataSource, DataManagerRequest.Skip); - //Add custom logic here if needed and remove above method + recordId = intValue; } - if (DataManagerRequest.Take != 0) + else if (value is TransactionModel transaction) { - // Taking - DataSource = DataOperations.PerformTake(DataSource, DataManagerRequest.Take); - //Add custom logic here if needed and remove above method + recordId = transaction.Id; } - return DataManagerRequest.RequiresCounts ? new DataResult() { Result = DataSource, Count = TotalRecordsCount } : (object)DataSource; + else if (int.TryParse(value?.ToString(), out int parsedValue)) + { + recordId = parsedValue; + } + + if (recordId.HasValue && recordId.Value > 0) + { + await _transactionService!.RemoveTransactionAsync(recordId); + } + return value; } } -{% endhighlight %} +``` +In **Data/TransactionRepository.cs**, implement the delete method: -### Handling grouping operation +```csharp +public async Task RemoveTransactionAsync(int? key) +{ + // Find the transaction + var transaction = await _context.Transactions.FindAsync(key); + if (transaction == null) + throw new KeyNotFoundException($"Transaction with ID {key} not found"); + + // Remove and save + _context.Transactions.Remove(transaction); + await _context.SaveChangesAsync(); +} +``` +Now transactions are removed from the database and the grid UI reflects the changes immediately. -When implementing `CustomAdaptor`, grouping is managed by 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. +**Batch update** -The built-in [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 in the [DataUtil](https://help.syncfusion.com/cr/blazor/Syncfusion.Blazor.Data.DataUtil.html) class applies grouping logic based on the configuration in the [DataManagerRequest](https://help.syncfusion.com/cr/blazor/Syncfusion.Blazor.DataManagerRequest.html). Custom grouping logic can also be implemented when specific requirements exist. +Batch operations aggregate multiple insertions, updates, and deletions into a single request, reducing network overhead and enabling transactional consistency by persisting all changes atomically to the MySQL Server database. -{% highlight razor %} +In **Home.razor** implement `BatchUpdateAsync` to process multiple record changes in a single request: + +```csharp public class CustomAdaptor : DataAdaptor { - public OrderData OrderService = new OrderData(); - // Performs data read operation - public override async Task ReadAsync(DataManagerRequest DataManagerRequest, string Key = null) + public override async Task BatchUpdateAsync(DataManager dataManager, object changed, object added, object deleted, string keyField, string key, int? dropIndex) { - IEnumerable DataSource = await OrderService.GetOrdersAsync(); - int TotalRecordsCount = DataSource.Cast().Count(); - DataResult DataObject = new DataResult(); - // Handling Group operation in CustomAdaptor. - if (DataManagerRequest.Group != null) + // Process updated records + if (changed != null) { - IEnumerable ResultData = DataSource.ToList(); - // Grouping - foreach (var group in DataManagerRequest.Group) + foreach (var record in (IEnumerable)changed) { - ResultData = DataUtil.Group(ResultData, group, DataManagerRequest.Aggregates, 0, DataManagerRequest.GroupByFormatter); - //Add custom logic here if needed and remove above method + await _transactionService!.UpdateTransactionAsync(record); } - DataObject.Result = ResultData; - DataObject.Count = TotalRecordsCount; - return DataManagerRequest.RequiresCounts ? DataObject : (object)ResultData; } - return DataManagerRequest.RequiresCounts ? new DataResult() { Result = DataSource, Count = TotalRecordsCount } : (object)DataSource; - } -} -{% endhighlight %} - -N> For optimal performance, apply operations in the following sequence: **Searching → Filtering → Sorting → Aggregation → Paging → Grouping** in [ReadAsync](https://help.syncfusion.com/cr/blazor/Syncfusion.Blazor.DataAdaptor.html#Syncfusion_Blazor_DataAdaptor_ReadAsync_Syncfusion_Blazor_DataManagerRequest_System_String_) method. -```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 TotalRecordsCount = DataSource.Cast().Count(); - DataResult DataObject = new DataResult(); - // Handling both Grouping and Aggregation in CustomAdaptor. - if (DataManagerRequest.Aggregates != null || DataManagerRequest.Group != null) // Aggregation + // Process newly added records + if (added != null) { - if (DataManagerRequest.Group != null) + foreach (var record in (IEnumerable)added) { - 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; + await _transactionService!.AddTransactionAsync(record); } - else + } + + // Process deleted records + if (deleted != null) + { + foreach (var record in (IEnumerable)deleted) { - DataObject.Result = DataSource; + await _transactionService!.RemoveTransactionAsync(record.Id); } - DataObject.Count = TotalRecordsCount; - DataObject.Aggregates = DataUtil.PerformAggregation(DataSource, DataManagerRequest.Aggregates); - - return DataManagerRequest.RequiresCounts ? DataObject : (object)DataSource; } - return DataManagerRequest.RequiresCounts ? new DataResult() { Result = DataSource, Count = TotalRecordsCount } : (object)DataSource; + return key; } } ``` -### Handling CRUD operations - -The Syncfusion® Blazor DataGrid component supports Create, Read, Update, and Delete (CRUD) operations through the [GridEditSettings](https://help.syncfusion.com/cr/blazor/Syncfusion.Blazor.Grids.GridEditSettings.html) configuration. Multiple edit modes are available, including **Inline**, **Dialog**, and **Batch** editing. For details, refer to the [Editing](https://blazor.syncfusion.com/documentation/datagrid/editing) documentation. - -When using `CustomAdaptor`, CRUD operations are implemented by overriding the following methods of the [DataAdaptor](https://help.syncfusion.com/cr/blazor/Syncfusion.Blazor.DataAdaptor-1.html) class: +Now the adaptor supports bulk modifications with atomic database synchronization. All CRUD operations are now fully implemented, enabling comprehensive data management capabilities within the Blazor DataGrid. -* [Insert](https://help.syncfusion.com/cr/blazor/Syncfusion.Blazor.DataAdaptor.html#Syncfusion_Blazor_DataAdaptor_Insert_Syncfusion_Blazor_DataManager_System_Object_System_String_) / [InsertAsync](https://help.syncfusion.com/cr/blazor/Syncfusion.Blazor.DataAdaptor.html#Syncfusion_Blazor_DataAdaptor_InsertAsync_Syncfusion_Blazor_DataManager_System_Object_System_String_) – Handles record insertion. -* [Update](https://help.syncfusion.com/cr/blazor/Syncfusion.Blazor.DataAdaptor.html#Syncfusion_Blazor_DataAdaptor_Update_Syncfusion_Blazor_DataManager_System_Object_System_String_System_String_) / [UpdateAsync](https://help.syncfusion.com/cr/blazor/Syncfusion.Blazor.DataAdaptor.html#Syncfusion_Blazor_DataAdaptor_UpdateAsync_Syncfusion_Blazor_DataManager_System_Object_System_String_System_String_) – Handles record updates. -* [Remove](https://help.syncfusion.com/cr/blazor/Syncfusion.Blazor.DataAdaptor.html#Syncfusion_Blazor_DataAdaptor_Remove_Syncfusion_Blazor_DataManager_System_Object_System_String_System_String_) / [RemoveAsync](https://help.syncfusion.com/cr/blazor/Syncfusion.Blazor.DataAdaptor.html#Syncfusion_Blazor_DataAdaptor_RemoveAsync_Syncfusion_Blazor_DataManager_System_Object_System_String_System_String_) – Handles record deletion. -* [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__) / [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__) – Handles batch operations (insert, update, delete). - -Each method can be customized to execute SQL commands against the **Microsoft SQL Server** database. - -{% highlight razor %} - - - - - - - - - - - -{% endhighlight %} - -> * Normal(Inline) editing is the default [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, set the [IsPrimaryKey](https://help.syncfusion.com/cr/blazor/Syncfusion.Blazor.Grids.GridColumn.html#Syncfusion_Blazor_Grids_GridColumn_IsPrimaryKey) property to **true** for a column that contains unique values. -> * If the database includes an auto-generated column, set the [IsIdentity](https://help.syncfusion.com/cr/blazor/Syncfusion.Blazor.Grids.GridColumn.html#Syncfusion_Blazor_Grids_GridColumn_IsIdentity) property for that column to disable editing during **add** or **update** operations. - -**Insert Operation:** - -To implement record insertion, 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 in the `CustomAdaptor` class. - -{% 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 implement record updates, 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 in the `CustomAdaptor` class. - -{% 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 record deletion, 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 in the `CustomAdaptor` class. - -{% 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 implement batch updates such as insert, update, and delete in a single request, 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 in the `CustomAdaptor` class. - -{% highlight razor %} -/// -/// /// 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. -/// 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 %} +--- +### Running the sample -![Blazor DataGrid component bound with MySQL Server data](../images/blazor-Grid-Ms-SQl-databinding-Gif.gif) +Build and run the application: +```powershell +dotnet build +dotnet run +``` -> A complete sample implementation is available in the [GitHub](https://github.com/SyncfusionExamples/connecting-databases-to-blazor-datagrid-component/tree/master/Binding%20MySQL%20database%20using%20CustomAdaptor) repository. +> A complete sample implementation is available in the [GitHub](https://github.com/SyncfusionExamples/connecting-databases-to-blazor-datagrid-component/tree/master/Binding%20MySQL%20database%20using%20CustomAdaptor) repository. \ No newline at end of file