diff --git a/connecting-to-database/syncfusion-react-grid-EntityFrameWork/README.md b/connecting-to-database/syncfusion-react-grid-EntityFrameWork/README.md new file mode 100644 index 0000000..617e50f --- /dev/null +++ b/connecting-to-database/syncfusion-react-grid-EntityFrameWork/README.md @@ -0,0 +1,337 @@ +# React Grid with SQL Server and Entity Framework Core + +## Project Overview + +This repository demonstrates a production-ready pattern for binding **SQL Server** data to **Syncfusion React Grid** using **Entity Framework Core (EF Core)**. The sample application provides complete CRUD (Create, Read, Update, Delete) operations, filtering, sorting, paging, and batch updates. The implementation follows industry best practices using ASP.NET Core Web API, DbContext, Entity Framework Core, and a custom adaptor for seamless grid-to-server communication. + +## Key Features + +- **SQL Server–Entity Framework Core Integration**: Models, DbContext, and Entity Framework Core for database operations +- **Syncfusion React Grid**: Built-in search, filter, sort, paging, and toolbar capabilities +- **Complete CRUD Operations**: Add, edit, delete, and batch update ticket records directly from the grid +- **CustomAdaptor Pattern**: Full control over grid data operations with RESTful API communication +- **ASP.NET Core Web API**: RESTful backend service with proper CORS configuration +- **Batch Operations Support**: Efficient handling of multiple add, update, and delete operations +- **Configurable Connection String**: Database credentials managed via **appsettings.json** + +## Prerequisites + +| Component | Version | Purpose | +|-----------|---------|---------| +| Visual Studio 2022 | 17.0 or later | Development IDE with React and ASP.NET Core workload | +| .NET SDK | .NET 10.0 or later | Runtime and build tools for backend API | +| Node.js | 18.x or later | JavaScript runtime for React development | +| npm | 11.x or later | Package manager | +| SQL Server | 2019 or later | Database server | +| Microsoft.EntityFrameworkCore | 10.0.2 or later | Core framework for database operations | +| Microsoft.EntityFrameworkCore.SqlServer | 10.0.2 or later | SQL Server provider for Entity Framework Core | +| Syncfusion.EJ2.Base | Latest | Backend support for Syncfusion components | +| @syncfusion/ej2-react-grids | Latest | React Grid component | +| @syncfusion/ej2-data | Latest | Data management utilities | + +## Quick Start + +1. **Clone the repository** + ```bash + git clone + cd syncfusion-react-grid-EntityFrameWork + ``` + +2. **Create the database and table** + + Open SQL Server Management Studio (SSMS) or SQL Server Express and run: + ```sql + -- Create Database + IF NOT EXISTS (SELECT * FROM sys.databases WHERE name = 'TicketsDb') + BEGIN + CREATE DATABASE TicketsDb; + END + GO + + USE TicketsDb; + GO + + -- Create Tickets Table + IF NOT EXISTS (SELECT * FROM sys.tables WHERE name = 'Tickets') + BEGIN + CREATE TABLE dbo.Tickets ( + TicketId INT PRIMARY KEY IDENTITY(1,1), + PublicTicketId VARCHAR(50) NOT NULL UNIQUE, + Title VARCHAR(200) NULL, + Description TEXT NULL, + Category VARCHAR(100) NULL, + Department VARCHAR(100) NULL, + Assignee VARCHAR(100) NULL, + CreatedBy VARCHAR(100) NULL, + Status VARCHAR(50) NOT NULL DEFAULT 'Open', + Priority VARCHAR(50) NOT NULL DEFAULT 'Medium', + ResponseDue DATETIME2 NULL, + DueDate DATETIME2 NULL, + CreatedAt DATETIME2 NOT NULL DEFAULT GETDATE(), + UpdatedAt DATETIME2 NOT NULL DEFAULT GETDATE() + ); + END + GO + + -- Insert Sample Data (Optional) + INSERT INTO dbo.Tickets (PublicTicketId, Title, Description, Category, Department, Assignee, CreatedBy, Status, Priority, ResponseDue, DueDate, CreatedAt, UpdatedAt) + VALUES + ('NET-1001', 'Network Connectivity Issue', 'Users unable to connect to the VPN', 'Network Issue', 'Network Ops', 'John Doe', 'Alice Smith', 'Open', 'High', '2026-01-14 10:00:00', '2026-01-15 17:00:00', '2026-01-13 10:15:30', '2026-01-13 10:15:30'), + ('NET-1002', 'Server Performance Degradation', 'Email server responding slowly', 'Performance', 'Infrastructure', 'Emily White', 'Bob Johnson', 'InProgress', 'Critical', '2026-01-13 15:00:00', '2026-01-14 17:00:00', '2026-01-13 11:20:10', '2026-01-13 11:20:10'); + GO + ``` + +3. **Update the connection string** + + Open (**Grid_EntityFramework.Server/appsettings.json**) and configure the SQL Server connection: + ```json + { + "ConnectionStrings": { + "TicketsDb": "Server=localhost;Database=TicketsDb;Trusted_Connection=True;TrustServerCertificate=True;" + }, + "Logging": { + "LogLevel": { + "Default": "Information", + "Microsoft.AspNetCore": "Warning" + } + }, + "AllowedHosts": "*" + } + ``` + +4. **Install server dependencies and run the API** + ```bash + cd Grid_EntityFramework.Server + dotnet build + dotnet run + ``` + The API will run at `http://localhost:5018` (or the port shown in terminal). + +5. **Install client dependencies and run the React app** + + Open a new terminal: + ```bash + cd grid_entityframework.client + npm install + npm run dev + ``` + +6. **Open the application** + + Navigate to the local URL displayed in the terminal (typically `http://localhost:5173`). + +## Configuration + +### Connection String + +The connection string in **appsettings.json** contains the following components: + +| Component | Description | Example | +|-----------|-------------|---------| +| Server | SQL Server instance address | `localhost` or `.\SQLEXPRESS` | +| Database | Database name | `TicketsDb` | +| Trusted_Connection | Windows Authentication | `True` (for local development) | +| TrustServerCertificate | Certificate validation | `True` (for local development) | + +**Security Note**: For production environments, store sensitive credentials using: +- User secrets for development +- Environment variables for production +- Azure Key Vault or similar secure storage solutions + +For SQL Server Authentication (username/password): +``` +Server=your-server;Database=TicketsDb;User ID=sa;Password=;TrustServerCertificate=True +``` + +### API Base URL + +The React client connects to the API server. Update the URL in **grid_entityframework.client/src/App.tsx** if your API runs on a different port: + +```typescript +const dataManager = useMemo(() => new DataManager({ + url: 'http://localhost:5018/api/tickets/url', + insertUrl: 'http://localhost:5018/api/tickets/insert', + updateUrl: 'http://localhost:5018/api/tickets/update', + removeUrl: 'http://localhost:5018/api/tickets/remove', + batchUrl: 'http://localhost:5018/api/tickets/batch', + adaptor: new CustomAdaptor(), +}), []); +``` + +## Project Layout + +| File/Folder | Purpose | +|-------------|---------| +| **Backend (Grid_EntityFramework.Server)** | | +| `/Models/Ticket.cs` | Entity model representing the Tickets table with EF Core annotations | +| `/Data/TicketsDbContext.cs` | Entity Framework Core DbContext for database operations | +| `/Controllers/TicketsController.cs` | ASP.NET Core Web API controller with CRUD endpoints | +| `/Program.cs` | Service registration, EF Core configuration, and CORS setup | +| `/appsettings.json` | Application configuration including connection string | +| **Frontend (grid_entityframework.client)** | | +| `/src/App.tsx` | Main React component with Grid configuration and DataManager | +| `/src/CustomAdaptor.ts` | Custom data adaptor extending UrlAdaptor for handling grid operations | +| `/src/index.css` | Global CSS styles including Syncfusion theme imports | +| `/src/main.tsx` | React application entry point | +| `/package.json` | NPM dependencies and scripts | +| `/vite.config.ts` | Vite build configuration | + +## Common Tasks + +### Add a Ticket +1. Click the **Add** button in the grid toolbar +2. Fill in the form fields (Public Ticket ID, Title, Department, Status, Priority, etc.) +3. Click **Update** to persist the record to the database +4. The grid automatically refreshes with the new ticket + +### Edit a Ticket +1. Select a row in the grid +2. Click the **Edit** button in the toolbar (or double-click the row) +3. Modify the required fields using the appropriate editors +4. Click **Update** to save changes +5. The database is immediately updated via Entity Framework Core + +### Delete a Ticket +1. Select a row in the grid +2. Click the **Delete** button in the toolbar +3. Confirm the deletion +4. The record is removed from the database and grid + +### Search Records +1. Use the **Search** box in the toolbar +2. Enter keywords to filter records across configured columns +3. Results are displayed in real-time + +### Filter Records +1. Click the filter icon in any column header +2. Select filter criteria (equals, contains, greater than, etc.) +3. Click **Filter** to apply +4. Results are updated on the server and returned to the grid + +### Sort Records +1. Click the column header to sort ascending +2. Click again to sort descending +3. Hold **Shift** and click another column for multi-column sorting + +### Batch Operations +1. Enable batch mode by setting `mode: 'Batch'` in `editSettings` +2. Make multiple changes (add, edit, delete) in the grid +3. Click **Update** to send all changes in a single batch request +4. All operations are processed together on the server using Entity Framework Core + +## Architecture Overview + +### Backend Flow + +1. **Client Request**: React Grid (via CustomAdaptor) sends HTTP POST requests to `/api/tickets/*` endpoints +2. **Controller**: `TicketsController` receives the request with `DataManagerRequest` parameters +3. **DataOperations**: Syncfusion's `DataOperations` class processes filtering, sorting, and paging +4. **DbContext**: Entity Framework Core executes LINQ queries against the database +5. **Database**: SQL Server processes the query and returns results +6. **Response**: Data flows back through DbContext → controller → HTTP response → CustomAdaptor → Grid + +### CustomAdaptor + +The `CustomAdaptor` extends Syncfusion's `UrlAdaptor` and handles: +- **Read operations**: POST requests with query parameters for filtering, sorting, paging +- **CRUD operations**: POST requests for insert/update/delete +- **Batch operations**: Handles multiple changes in a single request +- **Response transformation**: Processes server responses into Grid-compatible format (adds SNo field) + +### Entity Framework Core Pattern + +Entity Framework Core methods and patterns used: + +| Method/Pattern | Description | +|----------------|-------------| +| `AsNoTracking()` | Read-only queries for better performance | +| `Add()` | Adds new entities to the context | +| `Entry().State = Modified` | Updates existing entities | +| `Remove()` | Deletes entities from the database | +| `SaveChanges()` | Persists all changes to the database | +| `DataOperations` | Syncfusion utility for applying Grid operations to IQueryable | + +### API Endpoints + +| Operation | HTTP Method | Endpoint | Purpose | +|-----------|-------------|----------|---------| +| Read/Filter/Sort/Page | POST | `/api/tickets/url` | Retrieves data with applied filters, sorting, and paging | +| Insert | POST | `/api/tickets/insert` | Adds a new ticket record | +| Update | POST | `/api/tickets/update` | Updates an existing ticket record | +| Delete | POST | `/api/tickets/remove` | Deletes a ticket record | +| Batch Operations | POST | `/api/tickets/batch` | Handles multiple add, update, and delete operations in a single request | + +## Troubleshooting + +### Connection Error +- Verify SQL Server is running and accessible on the specified host +- Confirm the database name and authentication method are correct +- For Windows Authentication, ensure user account has access to SQL Server +- For SQL Server Authentication, verify the username and password +- Ensure the `TicketsDb` database exists + +### Missing Tables +- Verify the SQL script was executed successfully in SQL Server Management Studio +- Run the database creation script again +- Confirm the table name is `[dbo].[Tickets]` with correct schema +- Check that the unique constraint on `PublicTicketId` was created + +### CORS Issues +- Verify CORS is configured in `Program.cs` with the "dev" policy +- Check that the policy allows the client origin (`AllowAnyOrigin()`) +- Clear browser cache and restart both server and client +- Ensure `app.UseCors("dev")` is called before `app.MapControllers()` + +### Grid Not Loading Data +- Check browser console for errors +- Verify the API is running and accessible at the configured URL +- Test the API endpoint directly using Postman or browser (POST to `/api/tickets/url`) +- Ensure the `CustomAdaptor` is correctly configured in `App.tsx` +- Check that Entity Framework Core is properly configured in `Program.cs` + +### Entity Framework Mapping Issues +- Ensure the `Ticket` model properties match the database column names +- Check that the DbContext is correctly configured with table and schema +- Verify that the connection string points to the correct database +- Use Entity Framework Core migrations if schema changes are needed + +### Identity Column Issues +- Ensure `TicketId` is marked with `[DatabaseGenerated(DatabaseGeneratedOption.Identity)]` +- When inserting, set `ticket.TicketId = 0` to let SQL Server generate the ID +- Verify that the database column has `IDENTITY(1,1)` specified + +### JSON Serialization Issues +- The API uses Newtonsoft.Json with `NullValueHandling.Ignore` to prevent null issues +- Ensure the client sends proper JSON structure with `{ value: data }` wrapper +- Check that date/time values are in ISO 8601 format + +### Version Conflicts +- Align Entity Framework Core, SQL Server provider, and Syncfusion package versions +- Run `dotnet restore` for server and `npm install` for client to update packages +- Check `package.json` and `.csproj` files for conflicting version constraints +- Ensure all packages are compatible with .NET 10.0 + +## Reference +The [user guide](https://ej2.syncfusion.com/react/documentation/grid/connecting-to-orm/entity-framework) provides detailed directions in a clear, step-by-step format. + +## Reference +The [user guide](https://ej2.syncfusion.com/react/documentation/grid/connecting-to-orm/dapper) provides detailed directions in a clear, step-by-step format. + +# Steps to download GitHub samples using DownGit + +1. **Open the DownGit Website** + + Go to the official DownGit tool: https://downgit.github.io/#/home +2. **Copy the GitHub URL** + + - Navigate to the sample folder you want to download and copy its URL. + - Example : https://github.com/SyncfusionExamples/ej2-react-grid-samples/tree/master/connecting-to-database/syncfusion-react-grid-EntityFrameWork + +3. **Paste the URL into DownGit** + + In the DownGit input box, paste the copied GitHub URL. + +4. **Download the ZIP** + + - Click **Download**. + - DownGit will generate a ZIP file of the selected folder, which you can save and extract locally. \ No newline at end of file diff --git a/connecting-to-database/syncfusion-react-grid-MSSQL/README.md b/connecting-to-database/syncfusion-react-grid-MSSQL/README.md new file mode 100644 index 0000000..e9ee758 --- /dev/null +++ b/connecting-to-database/syncfusion-react-grid-MSSQL/README.md @@ -0,0 +1,316 @@ +# React Grid with SQL Server and ADO.NET SqlClient + +## Project Overview + +This repository demonstrates a production-ready pattern for binding **MSSQL Server** data to **Syncfusion React Grid** using **ADO.NET SqlClient**. The sample application provides complete CRUD (Create, Read, Update, Delete) operations, filtering, sorting, paging, and batch updates. The implementation follows industry best practices using ASP.NET Core Web API, repository pattern, and a custom adaptor for seamless grid-to-server communication. + +## Key Features + +- **MSSQL Server–SqlClient Integration**: Direct, high-performance ADO.NET access to SQL Server with full SQL control +- **Syncfusion React Grid**: Built-in search, filter, sort, paging, and toolbar capabilities +- **Complete CRUD Operations**: Add, edit, delete, and batch update ticket records directly from the grid +- **Repository Pattern**: Clean separation of concerns with dependency injection support +- **CustomAdaptor**: Full control over grid data operations (read, search, filter, sort, page) +- **ASP.NET Core Web API**: RESTful backend service with proper CORS configuration +- **Configurable Connection String**: Database credentials managed via **appsettings.json** + +## Prerequisites + +| Component | Version | Purpose | +|-----------|---------|---------| +| Visual Studio 2022 | 17.0 or later | Development IDE with React and ASP.NET Core workload | +| .NET SDK | 8.0 or later | Runtime and build tools for backend API | +| Node.js | 18.x or later | JavaScript runtime for React development | +| npm | 11.x or later | Package manager | +| SQL Server | 2019 or later | Database server | +| Microsoft.Data.SqlClient | Latest | Official SQL Server data provider for ADO.NET | +| Syncfusion.EJ2 | Latest | Server helpers (DataManagerRequest, DataOperations) | +| @syncfusion/ej2-react-grids | Latest | React Grid component | +| @syncfusion/ej2-data | Latest | Data management utilities | + +## Quick Start + +1. **Clone the repository** + ```bash + git clone + cd syncfusion-react-grid-MSSQL + ``` + +2. **Create the database and table** + + Open SQL Server Management Studio (SSMS) or any SQL Server client and run: + ```sql + -- Create Database + IF NOT EXISTS (SELECT * FROM sys.databases WHERE name = 'NetworkSupportDB') + BEGIN + CREATE DATABASE NetworkSupportDB; + END + GO + + USE NetworkSupportDB; + GO + + -- Create Tickets Table + IF NOT EXISTS (SELECT * FROM sys.tables WHERE name = 'Tickets') + BEGIN + CREATE TABLE dbo.Tickets ( + TicketId INT PRIMARY KEY IDENTITY(1,1), + PublicTicketId VARCHAR(50) NOT NULL UNIQUE, + Title VARCHAR(200) NULL, + Description TEXT NULL, + Category VARCHAR(100) NULL, + Department VARCHAR(100) NULL, + Assignee VARCHAR(100) NULL, + CreatedBy VARCHAR(100) NULL, + Status VARCHAR(50) NOT NULL DEFAULT 'Open', + Priority VARCHAR(50) NOT NULL DEFAULT 'Medium', + ResponseDue DATETIME2 NULL, + DueDate DATETIME2 NULL, + CreatedAt DATETIME2 NOT NULL DEFAULT GETDATE(), + UpdatedAt DATETIME2 NOT NULL DEFAULT GETDATE() + ); + END + GO + + -- Insert Sample Data (Optional) + INSERT INTO dbo.Tickets (PublicTicketId, Title, Description, Category, Department, Assignee, CreatedBy, Status, Priority, ResponseDue, DueDate, CreatedAt, UpdatedAt) + VALUES + ('NET-1001', 'Network Connectivity Issue', 'Users unable to connect to the VPN', 'Network Issue', 'Network Ops', 'John Doe', 'Alice Smith', 'Open', 'High', '2026-01-14 10:00:00', '2026-01-15 17:00:00', '2026-01-13 10:15:30', '2026-01-13 10:15:30'), + ('NET-1002', 'Server Performance Degradation', 'Email server responding slowly', 'Performance', 'Infrastructure', 'Emily White', 'Bob Johnson', 'InProgress', 'Critical', '2026-01-13 15:00:00', '2026-01-14 17:00:00', '2026-01-13 11:20:10', '2026-01-13 11:20:10'); + GO + ``` + +3. **Update the connection string** + + Open **Grid_MSSQL.Server/appsettings.json** and configure the SQL Server connection: + + ```json + { + "ConnectionStrings": { + "TicketDb": "Data Source=localhost;Initial Catalog=NetworkSupportDB;Integrated Security=True;Connect Timeout=30;Encrypt=False;Trust Server Certificate=False;Application Intent=ReadWrite;Multi Subnet Failover=False" + }, + "Logging": { + "LogLevel": { + "Default": "Information", + "Microsoft.AspNetCore": "Warning" + } + }, + "AllowedHosts": "*" + } + ``` + +4. **Install server dependencies and run the API** + ```bash + cd Grid_MSSQL.Server + dotnet build + dotnet run + ``` + The API will run at `http://localhost:5239` (or the port shown in terminal). + +5. **Install client dependencies and run the React app** + + Open a new terminal: + ```bash + cd grid_mssql.client + npm install + npm run dev + ``` + +6. **Open the application** + + Navigate to the local URL displayed in the terminal (typically `http://localhost:5173`). + +## Configuration + +### Connection String + +The connection string in **appsettings.json** contains the following components: + +| Component | Description | Example | +|-----------|-------------|---------| +| Data Source | SQL Server instance name or IP address | `localhost` or `.\SQLEXPRESS` | +| Initial Catalog | Database name | `NetworkSupportDB` | +| Integrated Security | Windows Authentication | `True` (for local development) | +| Connect Timeout | Connection timeout in seconds | `30` | +| Encrypt | Enable encryption for the connection | `False` (for local development) | +| Trust Server Certificate | Trust the server certificate | `False` | +| Application Intent | Connection intent (ReadWrite or ReadOnly) | `ReadWrite` | +| Multi Subnet Failover | Used in failover clustering scenarios | `False` | + +**Security Note**: For production environments, store sensitive credentials using: +- User secrets for development +- Environment variables for production +- Azure Key Vault or similar secure storage solutions + +For SQL Server Authentication (username/password): +``` +Data Source=your-server;Initial Catalog=NetworkSupportDB;User ID=sa;Password=;Encrypt=True;TrustServerCertificate=True +``` + +### API Base URL + +The React client connects to the API server. Update the `BASE_URL` in **grid_mssql.client/src/App.tsx** if your API runs on a different port: + +```typescript +const BASE_URL = 'http://localhost:5239/api/tickets'; +``` + +## Project Layout + +| File/Folder | Purpose | +|-------------|---------| +| **Backend (Grid_MSSQL.Server)** | | +| `/Data/Tickets.cs` | Entity model representing the Tickets table | +| `/Data/TicketRepository.cs` | Repository class providing async CRUD methods using ADO.NET SqlClient | +| `/Controllers/TicketsController.cs` | ASP.NET Core Web API controller with CRUD and batch endpoints | +| `/Program.cs` | Service registration, CORS configuration, and app setup | +| `/appsettings.json` | Application configuration including connection string | +| **Frontend (grid_mssql.client)** | | +| `/src/App.tsx` | Main React component with Grid configuration and column templates | +| `/src/CustomAdaptor.ts` | Custom data adaptor extending UrlAdaptor for handling grid operations | +| `/src/index.css` | Global CSS styles including Syncfusion theme imports | +| `/src/main.tsx` | React application entry point | +| `/package.json` | NPM dependencies and scripts | +| `/vite.config.ts` | Vite build configuration | + +## Common Tasks + +### Add a Ticket +1. Click the **Add** button in the grid toolbar +2. Fill in the form fields (Title, Status, Priority, Category, Department, Assignee, etc.) +3. Click **Update** to persist the record to the database +4. The system automatically generates a unique `PublicTicketId` (e.g., NET-1001) + +### Edit a Ticket +1. Select a row in the grid +2. Click the **Edit** button in the toolbar (or double-click the row) +3. Modify the required fields using the appropriate editors +4. Click **Update** to save changes + +### Delete a Ticket +1. Select a row in the grid +2. Click the **Delete** button in the toolbar +3. Confirm the deletion in the dialog + +### Search Records +1. Use the **Search** box in the toolbar +2. Enter keywords to filter records (searches across configured columns) + +### Filter Records +1. Click the filter icon in any column header +2. Select filter criteria (equals, contains, greater than, etc.) +3. Click **Filter** to apply + +### Sort Records +1. Click the column header to sort ascending +2. Click again to sort descending +3. Hold **Shift** and click another column for multi-column sorting + +## Architecture Overview + +### Backend Flow + +1. **Client Request**: React Grid (via CustomAdaptor) sends HTTP POST requests to `/api/tickets` endpoints +2. **Controller**: `TicketsController` receives the request with `DataManagerRequest` parameters +3. **DataOperations**: Syncfusion's `DataOperations` class applies searching, filtering, sorting, and paging to in-memory data +4. **Repository**: `TicketRepository` uses ADO.NET `SqlConnection` / `SqlCommand` to execute parameterized SQL queries +5. **Database**: SQL Server processes the query and returns results +6. **Response**: Data flows back through repository → controller → HTTP response → CustomAdaptor → Grid + +### CustomAdaptor + +The `CustomAdaptor` extends Syncfusion's `UrlAdaptor` and handles: +- **Read operations**: POST requests with `DataManagerRequest` payload for filtering, sorting, paging +- **CRUD operations**: POST requests wrapping the record in `{ value: data }` for insert/update/delete +- **Batch operations**: POST request with `{ added, changed, deleted }` arrays +- **Response transformation**: Processes server responses into Grid-compatible format + +### Repository Pattern with SqlClient + +ADO.NET methods used in `TicketRepository`: + +| Method | Description | +|--------|-------------| +| `GetTicketsAsync` | Executes a SELECT on `Tickets`, maps rows to `Tickets` objects, returns full list ordered by `TicketId` | +| `GeneratePublicTicketIdAsync` | Finds the current max numeric suffix in `PublicTicketId` (format `NET-####`) and returns the next value | +| `InsertAsync` | Auto-generates `PublicTicketId` if blank, sets timestamps, inserts via `INSERT … SELECT SCOPE_IDENTITY()`, returns entity with new `TicketId` | +| `UpdateAsync` | Updates all mutable fields by `TicketId`, refreshes `UpdatedAt`, returns updated entity | +| `DeleteAsync` | Deletes the ticket matching `TicketId`, returns number of affected rows | + +### API Endpoints + +| Operation | HTTP Method | Endpoint | Purpose | +|-----------|-------------|----------|---------| +| Read/Filter/Sort/Page | POST | `/api/tickets` | Retrieves data with applied filters, sorting, and paging | +| Insert | POST | `/api/tickets/insert` | Adds a new ticket record | +| Update | POST | `/api/tickets/update` | Updates an existing ticket record | +| Delete | POST | `/api/tickets/remove` | Deletes a ticket record | +| Batch | POST | `/api/tickets/batch` | Handles multiple add, update, and delete operations in a single request | +| Health Check | GET | `/api/tickets/ping` | Verifies the API is running | + +## Troubleshooting + +### Connection Error +- Verify SQL Server is running and accessible on the specified host +- Confirm the `Data Source`, `Initial Catalog`, and authentication method are correct +- For Windows Authentication, ensure the user account has access to SQL Server +- For SQL Server Authentication, verify the username and password +- Ensure the `NetworkSupportDB` database exists + +### Missing Tables +- Verify the SQL script was executed successfully in SQL Server Management Studio +- Run the database creation script again +- Confirm the table name is `[dbo].[Tickets]` with correct schema +- Check that the `UNIQUE` constraint on `PublicTicketId` was created + +### CORS Issues +- Verify CORS is configured in `Program.cs` with `app.UseCors()` +- Check that the default policy allows any origin, header, and method +- Clear browser cache and restart both server and client +- Ensure `app.UseCors()` is called before `app.MapControllers()` + +### Grid Not Loading Data +- Check the browser console for errors +- Verify the API is running at the configured URL (use `GET /api/tickets/ping` to confirm) +- Test the read endpoint directly using Postman (POST to `/api/tickets` with body `{}`) +- Ensure the `CustomAdaptor` is correctly configured in `App.tsx` + +### SqlClient Mapping Issues +- Ensure the `Tickets` model property names match the database column names exactly +- Check that nullable columns (`?`) are handled correctly when reading `DBNull` values +- Verify parameterized queries use the correct SQL parameter types + +### PublicTicketId Not Generated +- Confirm `InsertAsync` is being called (not a direct SQL insert) +- Verify the `GeneratePublicTicketIdAsync` method can query the `Tickets` table +- Check that the `PublicTicketId` column has a `UNIQUE` constraint in the database + +### Version Conflicts +- Align `Microsoft.Data.SqlClient`, `Syncfusion.EJ2`, and other package versions +- Run `dotnet restore` for server and `npm install` for client to update packages +- Check `package.json` and `.csproj` for conflicting version constraints +- Verify all packages are compatible with .NET 8.0 + + +## Reference +The [user guide](https://ej2.syncfusion.com/react/documentation/grid/connecting-to-database/microsoft-sql-server) provides detailed directions in a clear, step-by-step format. + +# Steps to download GitHub samples using DownGit + +1. **Open the DownGit Website** + + Go to the official DownGit tool: https://downgit.github.io/#/home + +2. **Copy the GitHub URL** + + - Navigate to the sample folder you want to download and copy its URL. + - Example : https://github.com/SyncfusionExamples/ej2-react-grid-samples/tree/master/connecting-to-database/syncfusion-react-grid-MSSQL + +3. **Paste the URL into DownGit** + + In the DownGit input box, paste the copied GitHub URL. + +4. **Download the ZIP** + + - Click **Download**. + - DownGit will generate a ZIP file of the selected folder, which you can save and extract locally. \ No newline at end of file diff --git a/connecting-to-database/syncfusion-react-grid-MySQL/README.md b/connecting-to-database/syncfusion-react-grid-MySQL/README.md new file mode 100644 index 0000000..eafe9a5 --- /dev/null +++ b/connecting-to-database/syncfusion-react-grid-MySQL/README.md @@ -0,0 +1,334 @@ +# React Grid with MySQL and LINQ2DB + +## Project Overview + +This repository demonstrates a production-ready pattern for binding **MySQL Server** data to **Syncfusion React Grid** using **LINQ2DB lightweight ORM**. The sample application provides complete CRUD (Create, Read, Update, Delete) operations, filtering, sorting, paging, and batch updates. The implementation follows industry best practices using ASP.NET Core Web API, LINQ2DB for type-safe database queries, and a custom adaptor for seamless grid-to-server communication. + +## Key Features + +- **MySQL–LINQ2DB Integration**: Type-safe LINQ queries with minimal overhead compared to full ORMs like Entity Framework +- **Syncfusion React Grid**: Built-in search, filter, sort, paging, and toolbar capabilities +- **Complete CRUD Operations**: Add, edit, delete, and batch update transaction records directly from the grid +- **Lightweight ORM**: LINQ2DB provides fast, efficient database access with built-in parameterization +- **CustomAdaptor**: Full control over grid data operations (read, search, filter, sort, page) +- **ASP.NET Core Web API**: RESTful backend service with proper CORS configuration +- **Batch Transaction Support**: Database transactions ensure data consistency across batch operations +- **Configurable Connection String**: Database credentials managed via **appsettings.json** + +## Prerequisites + +| Component | Version | Purpose | +|-----------|---------|---------| +| Visual Studio 2022 | 17.0 or later | Development IDE with React and ASP.NET Core workload | +| .NET SDK | 8.0 or later | Runtime and build tools for backend API | +| Node.js | 18.x or later | JavaScript runtime for React development | +| npm | 11.x or later | Package manager | +| MySQL Server | 8.0.41 or later | Database server | +| linq2db | 6.1.0 or later | Lightweight ORM for database operations | +| linq2db.MySql | 6.1.0 or later | MySQL provider for LINQ2DB | +| MySqlConnector | 2.5.0 or later | Modern MySQL connector for .NET | +| Syncfusion.EJ2.Base | Latest | Server helpers (DataManagerRequest, QueryableOperation) | +| @syncfusion/ej2-react-grids | Latest | React Grid component | +| @syncfusion/ej2-data | Latest | Data management utilities | + +## Quick Start + +1. **Clone the repository** + ```bash + git clone + cd syncfusion-react-grid-MySQL + ``` + +2. **Create the database and table** + + Open MySQL Workbench or MySQL Command Line Client and run: + ```sql + -- Create Database + CREATE DATABASE IF NOT EXISTS transactiondb + CHARACTER SET utf8mb4 + COLLATE utf8mb4_general_ci; + USE transactiondb; + + -- Create Transactions Table + CREATE TABLE IF NOT EXISTS transactions ( + Id INT NOT NULL AUTO_INCREMENT PRIMARY KEY, + TransactionId VARCHAR(50) NOT NULL, + CustomerId INT NOT NULL, + OrderId INT, + InvoiceNumber VARCHAR(50), + Description VARCHAR(500), + Amount DECIMAL(18, 2) NOT NULL, + CurrencyCode VARCHAR(10), + TransactionType VARCHAR(50), + PaymentGateway VARCHAR(100), + CreatedAt DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP, + CompletedAt DATETIME, + Status VARCHAR(50) + ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_general_ci; + + -- 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'); + ``` + +3. **Update the connection string** + + Open **Grid_MySQL.Server/appsettings.json** and configure the MySQL connection: + ```json + { + "ConnectionStrings": { + "MySqlConn": "Server=localhost;Port=3306;Database=transactiondb;User Id=root;Password=;SslMode=None;" + }, + "Logging": { + "LogLevel": { + "Default": "Information", + "Microsoft.AspNetCore": "Warning" + } + }, + "AllowedHosts": "*" + } + ``` + +4. **Install server dependencies and run the API** + ```bash + cd Grid_MySQL.Server + dotnet restore + dotnet build + dotnet run + ``` + The API will run at `http://localhost:5283` (or the port shown in terminal). + +5. **Install client dependencies and run the React app** + + Open a new terminal: + ```bash + cd grid_mysql.client + npm install + npm run dev + ``` + +6. **Open the application** + + Navigate to the local URL displayed in the terminal (typically `http://localhost:5173`). + +## Configuration + +### Connection String + +The connection string in **appsettings.json** contains the following components: + +| Component | Description | Example | +|-----------|-------------|---------| +| Server | MySQL server address | `localhost` or `192.168.1.100` | +| Port | MySQL port number | `3306` | +| Database | Database name | `transactiondb` | +| User Id | MySQL username | `root` | +| Password | MySQL password | `` | +| SslMode | SSL encryption mode | `None` (for local dev), `Preferred` (for production) | + +**Security Note**: For production environments, store sensitive credentials using: +- User secrets for development +- Environment variables for production +- Azure Key Vault or similar secure storage solutions + +Example for production with SSL: +``` +Server=your-mysql-server.com;Port=3306;Database=transactiondb;User Id=admin;Password=;SslMode=Preferred; +``` + +### API Base URL + +The React client connects to the API server. Update the URL in `grid_mysql.client/src/App.tsx` if your API runs on a different port: + +```typescript +const dataManager = new DataManager({ + url: 'http://localhost:5283/api/grid/url', + insertUrl: 'http://localhost:5283/api/grid/insert', + updateUrl: 'http://localhost:5283/api/grid/update', + removeUrl: 'http://localhost:5283/api/grid/remove', + batchUrl: 'http://localhost:5283/api/grid/batch', + adaptor: new CustomAdaptor(), +}); +``` + +## Project Layout + +| File/Folder | Purpose | +|-------------|---------| +| **Backend (Grid_MySQL.Server)** | | +| `/Models/Transaction.cs` | Entity model representing the transactions table with LINQ2DB attributes | +| `/Data/AppDataConnection.cs` | LINQ2DB DataConnection class for MySQL database communication | +| `/Controllers/GridController.cs` | ASP.NET Core Web API controller with CRUD, batch, and query endpoints | +| `/Program.cs` | Service registration, LINQ2DB configuration, and CORS setup | +| `/appsettings.json` | Application configuration including MySQL connection string | +| **Frontend (grid_mysql.client)** | | +| `/src/App.tsx` | Main React component with Grid configuration and column definitions | +| `/src/CustomAdaptor.ts` | Custom data adaptor extending UrlAdaptor for handling grid operations | +| `/src/index.css` | Global CSS styles including Syncfusion theme imports | +| `/src/main.tsx` | React application entry point | +| `/package.json` | NPM dependencies and scripts | +| `/vite.config.ts` | Vite build configuration | + +## Common Tasks + +### Add a Transaction +1. Click the **Add** button in the grid toolbar +2. Fill in the form fields (Transaction ID, Customer ID, Amount, Status, etc.) +3. Click **Update** to persist the record to the database +4. The `CreatedAt` timestamp is automatically set to the current UTC time + +### Edit a Transaction +1. Select a row in the grid +2. Click the **Edit** button in the toolbar (or double-click the row) +3. Modify the required fields using the appropriate editors +4. Click **Update** to save changes + +### Delete a Transaction +1. Select a row in the grid +2. Click the **Delete** button in the toolbar +3. Confirm the deletion in the dialog + +### Search Records +1. Use the **Search** box in the toolbar +2. Enter keywords to filter records (searches across configured columns) + +### Filter Records +1. Click the filter icon in any column header +2. Select filter criteria (equals, contains, greater than, etc.) +3. Click **Filter** to apply + +### Sort Records +1. Click the column header to sort ascending +2. Click again to sort descending +3. Hold **Shift** and click another column for multi-column sorting + +## Architecture Overview + +### Backend Flow + +1. **Client Request**: React Grid (via CustomAdaptor) sends HTTP POST requests to `/api/grid/*` endpoints +2. **Controller**: `GridController` receives the request with `DataManagerRequest` parameters +3. **QueryableOperation**: Syncfusion's helper class applies searching, filtering, sorting, and paging to IQueryable +4. **DataConnection**: `AppDataConnection` uses LINQ2DB to execute queries against MySQL +5. **Database**: MySQL Server processes the query and returns results +6. **Response**: Data flows back through DataConnection → controller → HTTP response → CustomAdaptor → Grid + +### CustomAdaptor + +The `CustomAdaptor` extends Syncfusion's `UrlAdaptor` and handles: +- **Read operations**: POST requests with `DataManagerRequest` payload for filtering, sorting, paging +- **CRUD operations**: POST requests wrapping records with proper key handling +- **Batch operations**: POST request with `{ added, changed, deleted }` arrays using database transactions +- **Response transformation**: Processes server responses into Grid-compatible format + +### LINQ2DB with MySQL + +LINQ2DB features used in `AppDataConnection`: + +| Feature | Description | +|---------|-------------| +| `UseMySql()` | Configures LINQ2DB for MySQL 8.0+ with MySqlConnector provider | +| `GetTable()` | Returns an `ITable` for LINQ queries against a database table | +| `FromSql()` | Executes raw SQL queries (used for complex operations) | +| `InsertWithInt32IdentityAsync()` | Inserts a record and returns the auto-generated primary key | +| `UpdateAsync()` | Updates an entity and returns affected row count | +| `DeleteAsync()` | Deletes records matching a condition | +| `BeginTransactionAsync()` | Starts a database transaction for batch operations | + +### API Endpoints + +| Operation | HTTP Method | Endpoint | Purpose | +|-----------|-------------|----------|---------| +| Read/Filter/Sort/Page | POST | `/api/grid/url` | Retrieves data with applied filters, sorting, and paging | +| Insert | POST | `/api/grid/insert` | Adds a new transaction record | +| Update | POST | `/api/grid/update` | Updates an existing transaction record | +| Delete | POST | `/api/grid/remove` | Deletes a transaction record by ID | +| Batch | POST | `/api/grid/batch` | Handles multiple add, update, and delete operations in a single transaction | + +## Troubleshooting + +### Connection Error +- Verify MySQL Server is running and accessible at `localhost:3306` +- Confirm the database name, username, and password are correct +- Test the connection using MySQL Command Line or Workbench +- Ensure the `transactiondb` database exists +- Check that the user has permission to access the database + +### Missing Tables +- Verify the SQL script was executed successfully in MySQL Workbench +- Run the table creation script again if needed +- Confirm the table name is `transactions` in the `transactiondb` database +- Check that the `Id` column has `AUTO_INCREMENT` specified + +### CORS Issues +- Verify CORS is configured in `Program.cs` with `app.UseCors("cors")` +- Check that the policy allows any origin with `AllowAnyOrigin()` +- Clear browser cache and restart both server and client +- Ensure `app.UseCors("cors")` is called before `app.MapControllers()` + +### Grid Not Loading Data +- Check the browser console for errors +- Verify the API is running at the configured URL +- Test the API endpoint directly using Postman (POST to `/api/grid/url` with body `{}`) +- Ensure the `CustomAdaptor` is correctly configured in `App.tsx` +- Check that LINQ2DB is properly configured with MySQL in `AppDataConnection` + +### LINQ2DB Mapping Issues +- Ensure the `Transaction` model properties match the database column names +- Check that LINQ2DB attributes (`[Table]`, `[Column]`, `[PrimaryKey]`, `[Identity]`) are correct +- Verify nullable properties are marked with `?` in the model +- Use `[NotNull]` attribute for non-nullable columns + +### Identity/Auto-Increment Issues +- Ensure the `Id` column is marked with `[PrimaryKey, Identity]` in the model +- Verify the database column has `AUTO_INCREMENT` specified +- Check that `InsertWithInt32IdentityAsync()` is used for inserts (not standard `Insert()`) +- Confirm the returned `Id` is properly assigned back to the inserted entity + +### Batch Transaction Failures +- Check that the batch endpoint properly uses `BeginTransactionAsync()` +- Verify `CommitAsync()` is called after all operations +- Ensure each operation in batch (added, changed, deleted) is properly handled +- Check that the `Id` is correctly set before updates and deletes + +### MySQL Character Encoding Issues +- Ensure the database is created with `CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci` +- Verify the connection string does not have conflicting character set settings +- Check that table columns have `utf8mb4` charset specified + +### Version Conflicts +- Align `linq2db`, `linq2db.MySql`, `MySqlConnector`, and Syncfusion package versions +- Run `dotnet restore` for server and `npm install` for client to update packages +- Check `package.json` and `.csproj` for conflicting version constraints +- Verify all packages are compatible with .NET 8.0 + +### Port Already in Use +- If port 5283 or 5173 is in use, modify the port in: + - Server: `Grid_MySQL.Server/Properties/launchSettings.json` (change `applicationUrl`) + - Client: `grid_mysql.client/vite.config.ts` and update API URLs in `App.tsx` + +## Reference +The [user guide](https://ej2.syncfusion.com/react/documentation/grid/connecting-to-database/mysql-server) provides detailed directions in a clear, step-by-step format. + +# Steps to download GitHub samples using DownGit + +1. **Open the DownGit Website** + + Go to the official DownGit tool: https://downgit.github.io/#/home + +2. **Copy the GitHub URL** + + - Navigate to the sample folder you want to download and copy its URL. + - Example : https://github.com/SyncfusionExamples/ej2-react-grid-samples/tree/master/connecting-to-database/syncfusion-react-grid-MySQL + +3. **Paste the URL into DownGit** + + In the DownGit input box, paste the copied GitHub URL. + +4. **Download the ZIP** + + - Click **Download**. + - DownGit will generate a ZIP file of the selected folder, which you can save and extract locally. \ No newline at end of file diff --git a/connecting-to-database/syncfusion-react-grid-SQLite/README.md b/connecting-to-database/syncfusion-react-grid-SQLite/README.md new file mode 100644 index 0000000..acd93c5 --- /dev/null +++ b/connecting-to-database/syncfusion-react-grid-SQLite/README.md @@ -0,0 +1,312 @@ +# React Grid with SQLite and Entity Framework Core + +## Project Overview + +This repository demonstrates a production-ready pattern for binding **SQLite** data to **Syncfusion React Grid** using **Entity Framework Core (EF Core)**. SQLite is a lightweight, serverless, embedded database that is ideal for mobile applications, desktop applications, and small-to-medium scale web applications. The sample application provides complete CRUD (Create, Read, Update, Delete) operations, filtering, sorting, paging, and batch updates with a clean separation between the React frontend and ASP.NET Core backend. + +## Key Features + +- **SQLite–Entity Framework Core Integration**: Lightweight, serverless database with automatic SQL generation and migrations +- **Syncfusion React Grid**: Built-in search, filter, sort, paging, and toolbar capabilities +- **Complete CRUD Operations**: Add, edit, delete, and batch update asset records directly from the grid +- **Type Safety**: Strongly-typed LINQ queries with Entity Framework Core +- **CustomAdaptor**: Full control over grid data operations (read, search, filter, sort, page) +- **Database Transactions**: Batch operations are executed within database transactions for data consistency +- **ASP.NET Core Web API**: RESTful backend service with proper CORS configuration +- **Embedded Database**: SQLite database file stored on disk with configurable path + +## Prerequisites + +| Component | Version | Purpose | +|-----------|---------|---------| +| Visual Studio 2022 | 17.0 or later | Development IDE with ASP.NET Core and React workload | +| .NET SDK | 9.0 or later | Runtime and build tools for backend API | +| Node.js | 18.x or later | JavaScript runtime for React development | +| npm | 11.x or later | Package manager | +| SQLite | 3.0 or later | Embedded database engine | +| Microsoft.EntityFrameworkCore | 9.0.0 or later | Core framework for database operations | +| Microsoft.EntityFrameworkCore.Sqlite | 9.0.0 or later | SQLite provider for Entity Framework Core | +| Microsoft.EntityFrameworkCore.Tools | 9.0.0 or later | Tools for managing database migrations | +| Syncfusion.EJ2.AspNet.Core | Latest | Server helpers (DataManagerRequest, QueryableOperation) | +| @syncfusion/ej2-react-grids | Latest | React Grid component | +| @syncfusion/ej2-data | Latest | Data management utilities | + +## Quick Start + +1. **Clone the repository** + ```bash + git clone + cd syncfusion-react-grid-SQLite + ``` + +2. **Create the database and table** + + Open your file explorer or use **DB Browser for SQLite** or the `sqlite3` command-line tool to create an `asset.db` file, then run the following SQL script: + + ```sql + -- Create the IT Assets table + CREATE TABLE IF NOT EXISTS asset ( + Id INTEGER PRIMARY KEY AUTOINCREMENT, + AssetID TEXT NOT NULL UNIQUE, + AssetName TEXT NOT NULL, + AssetType TEXT NOT NULL, + Model TEXT, + SerialNumber TEXT NOT NULL, + InvoiceID TEXT, + AssignedTo TEXT, + Department TEXT, + PurchaseDate DATE, + PurchaseCost REAL, + WarrantyExpiry DATE, + Condition TEXT CHECK(Condition IN ('New', 'Good', 'Fair', 'Poor')) DEFAULT 'New', + LastMaintenance DATE, + Status TEXT CHECK(Status IN ('Active', 'In Repair', 'Retired', 'Available')) DEFAULT 'Available' + ); + + -- Insert Sample Data (Optional) + INSERT INTO asset (AssetID, AssetName, AssetType, Model, SerialNumber, InvoiceID, AssignedTo, Department, PurchaseDate, PurchaseCost, WarrantyExpiry, Condition, LastMaintenance, Status) + VALUES + ('AST-001', 'Dell Latitude Laptop', 'Laptop', 'Latitude 5520', 'SN-DEL-2024-001', 'INV-2023-0015', 'John Smith', 'IT', '2023-01-15', 1250.00, '2026-01-15', 'Good', '2024-06-10', 'Active'), + ('AST-002', 'HP ProBook Laptop', 'Laptop', 'ProBook 450 G8', 'SN-HP-2024-002', 'INV-2023-0042', 'Sarah Johnson', 'Finance', '2023-03-20', 1100.00, '2026-03-20', 'Good', '2024-05-15', 'Active'); + ``` + +3. **Update the connection string** + + Open `Grid_SQLite.Server/appsettings.json` and configure the SQLite database path: + + ```json + { + "Logging": { + "LogLevel": { + "Default": "Information", + "Microsoft.AspNetCore": "Warning" + } + }, + "AllowedHosts": "*", + "ConnectionStrings": { + "DefaultConnection": "Data Source=D:\\Database\\asset.db" + } + } + ``` + + **Note**: Update the path to match where you created the `asset.db` file on your system. + +4. **Install server dependencies and run the API** + + ```bash + cd Grid_SQLite.Server + dotnet build + dotnet run + ``` + + The API will run at `https://localhost:7116` (or the port shown in terminal). + +5. **Install client dependencies and run the React app** + + Open a new terminal: + + ```bash + cd grid_sqlite.client + npm install + npm run dev + ``` + +6. **Open the application** + + Navigate to the local URL displayed in the terminal (typically `http://localhost:5173`). + +## Configuration + +### Database Path + +The connection string in **appsettings.json** points to the SQLite database file: + +```json +"DefaultConnection": "Data Source=D:\\Database\\asset.db" +``` + +| Component | Description | Example | +|-----------|-------------|---------| +| Data Source | Path to the SQLite database file | `C:\Users\YourName\Documents\asset.db` or `/home/user/databases/asset.db` | + +**Notes**: +- SQLite stores the entire database in a single file +- The file path can be absolute (full path) or relative (relative to the application) +- The directory must exist; SQLite will create the file if it doesn't exist +- For production, use a centralized database location accessible to the application + +### API Base URL + +The React client connects to the API server. Update the URLs in (**grid_sqlite.client/src/App.tsx**) if your API runs on a different port: + +```typescript +const dataManager = useMemo( + () => + new DataManager({ + url: `https://localhost:7116/api/asset/url`, + insertUrl: `https://localhost:7116/api/asset/insert`, + updateUrl: `https://localhost:7116/api/asset/update`, + removeUrl: `https://localhost:7116/api/asset/remove`, + batchUrl: `https://localhost:7116/api/asset/batch`, + adaptor: new CustomAdaptor(), + }), + [], +); +``` + +## Project Layout + +| File/Folder | Purpose | +|-------------|---------| +| **Backend (Grid_SQLite.Server)** | | +| `/Data/Asset.cs` | Entity model representing the asset table with data annotations | +| `/Data/AssetDbContext.cs` | Entity Framework Core DbContext for SQLite database operations | +| `/Controllers/AssetController.cs` | ASP.NET Core Web API controller with CRUD and batch endpoints | +| `/Program.cs` | Service registration, EF Core configuration, and CORS setup | +| `/appsettings.json` | Application configuration including SQLite connection string | +| **Frontend (grid_sqlite.client)** | | +| `/src/App.tsx` | Main React component with Grid configuration and column templates | +| `/src/CustomAdaptor.ts` | Custom data adaptor extending UrlAdaptor for handling grid operations | +| `/src/index.css` | Global CSS styles including Syncfusion theme imports | +| `/src/main.tsx` | React application entry point | +| `/package.json` | NPM dependencies and scripts | +| `/vite.config.ts` | Vite build configuration | + +## Common Tasks + +### Add an Asset +1. Click the **Add** button in the grid toolbar +2. Fill in the form fields (Asset Name, Asset Type, Serial Number, Department, etc.) +3. Click **Update** to persist the record to the SQLite database +4. The asset is immediately saved with an auto-generated `Id` and appears in the grid + +### Edit an Asset +1. Select a row in the grid +2. Click the **Edit** button in the toolbar (or double-click the row) +3. Modify the required fields using the appropriate editors (date pickers, dropdowns, etc.) +4. Click **Update** to save changes to the database + +### Delete an Asset +1. Select a row in the grid +2. Click the **Delete** button in the toolbar +3. Confirm the deletion +4. The record is removed from the SQLite database and the grid + +### Search Records +1. Use the **Search** box in the toolbar +2. Enter keywords to filter records across all configured columns + +### Filter Records +1. Click the filter icon in any column header +2. Select filter criteria (equals, contains, date range, etc.) +3. Click **Filter** to apply + +### Sort Records +1. Click the column header to sort ascending +2. Click again to sort descending +3. Hold **Shift** and click another column for multi-column sorting + +## Architecture Overview + +### Backend Flow + +1. **Client Request**: React Grid (via CustomAdaptor) sends HTTP POST requests to `/api/asset/*` endpoints +2. **Controller**: `AssetController` receives the request with `DataManagerRequest` parameters +3. **QueryableOperation**: Syncfusion's helper class applies searching, filtering, sorting, and paging to IQueryable +4. **DbContext**: `AssetDbContext` uses Entity Framework Core to execute LINQ queries against SQLite +5. **Database**: SQLite processes the query and returns results +6. **Response**: Data flows back through DbContext → controller → HTTP response → CustomAdaptor → Grid + +### CustomAdaptor + +The `CustomAdaptor` extends Syncfusion's `UrlAdaptor` and handles: +- **Read operations**: POST requests with `DataManagerRequest` payload for filtering, sorting, paging +- **CRUD operations**: POST requests wrapping records with proper key handling +- **Batch operations**: POST request with `{ added, changed, deleted }` arrays executed as a database transaction +- **Response transformation**: Processes server responses into Grid-compatible format + +### Entity Framework Core with SQLite + +EF Core features used in the sample: + +| Feature | Description | +|---------|-------------| +| `DbSet` | Represents a table in the SQLite database | +| `OnModelCreating()` | Configures table mappings, column constraints, default values | +| `UseSqlite()` | Registers SQLite as the database provider | +| `SaveChangesAsync()` | Persists changes to the SQLite database | +| `FindAsync()` | Retrieves an entity by primary key | +| `ToListAsync()` | Executes the query and returns results | +| `BeginTransactionAsync()` | Starts a database transaction for batch operations | + +### API Endpoints + +| Operation | HTTP Method | Endpoint | Purpose | +|-----------|-------------|----------|---------| +| Read/Filter/Sort/Page | POST | `/api/asset/url` | Retrieves data with applied filters, sorting, and paging | +| Insert | POST | `/api/asset/insert` | Adds a new asset record | +| Update | POST | `/api/asset/update` | Updates an existing asset record | +| Delete | POST | `/api/asset/remove` | Deletes an asset record by ID | +| Batch | POST | `/api/asset/batch` | Handles multiple add, update, and delete operations in a single transaction | + +## Troubleshooting + +### Connection Error +- Verify the path in `DefaultConnection` points to a valid `asset.db` file +- Ensure the directory path exists and is accessible +- Check that the application has read/write permissions for the database file +- SQLite creates the file automatically if it doesn't exist (with proper permissions) + +### Missing Tables +- Verify the SQL script was executed successfully using DB Browser for SQLite or another SQLite client +- Check that the `asset` table exists in the `asset.db` file +- Run the database creation script again if needed +- Confirm column names and types match the `Asset` model + +### CORS Issues +- Verify CORS is configured in `Program.cs` with `app.UseCors("cors")` +- Check that the policy allows any origin with `AllowAnyOrigin()` +- Clear browser cache and restart both server and client +- Ensure `app.UseCors("cors")` is called before `app.MapControllers()` + +### Grid Not Loading Data +- Check the browser console for errors +- Verify the API is running at the configured URL +- Test the API endpoint directly using Postman (POST to `/api/asset/url` with body `{}`) +- Ensure the `CustomAdaptor` is correctly configured in `App.tsx` +- Check that Entity Framework Core is properly configured with SQLite in `Program.cs` + +### Entity Framework Mapping Issues +- Ensure the `Asset` model property names match the database column names +- Check that the DbContext is correctly configured with `OnModelCreating()` +- Verify nullable properties are marked with `?` in the model +- Use `[MaxLength]` attributes for string properties to match database column lengths + +### Database File Lock Issues +- Close any open SQLite clients or DB browsers that may lock the file +- Ensure the application has exclusive access to the database file +- Restart the ASP.NET Core server if the database file is locked +- In development, consider using an in-memory SQLite database for testing + +## Reference +The [user guide](https://ej2.syncfusion.com/react/documentation/grid/connecting-to-database/sqlite-server) provides detailed directions in a clear, step-by-step format. + +# Steps to download GitHub samples using DownGit + +1. **Open the DownGit Website** + + Go to the official DownGit tool: https://downgit.github.io/#/home + +2. **Copy the GitHub URL** + + - Navigate to the sample folder you want to download and copy its URL. + - Example : https://github.com/SyncfusionExamples/ej2-react-grid-samples/tree/master/connecting-to-database/syncfusion-react-grid-SQLite + +3. **Paste the URL into DownGit** + + In the DownGit input box, paste the copied GitHub URL. + +4. **Download the ZIP** + + - Click **Download**. + - DownGit will generate a ZIP file of the selected folder, which you can save and extract locally. \ No newline at end of file diff --git a/connecting-to-database/syncfusion-react-grid-dapper/README.md b/connecting-to-database/syncfusion-react-grid-dapper/README.md new file mode 100644 index 0000000..9f34499 --- /dev/null +++ b/connecting-to-database/syncfusion-react-grid-dapper/README.md @@ -0,0 +1,292 @@ +# React Grid with SQL Server and Dapper + +## Project Overview + +This repository demonstrates a production-ready pattern for binding **SQL Server** data to **Syncfusion React Grid** using **Dapper ORM**. The sample application provides complete CRUD (Create, Read, Update, Delete) operations, filtering, sorting, paging, and batch updates. The implementation follows industry best practices using ASP.NET Core Web API, Dapper micro-ORM, repository pattern, and a custom adaptor for seamless grid functionality. + +## Key Features + +- **SQL Server–Dapper Integration**: Lightweight and high-performance data access using Dapper with SQL Server +- **Syncfusion React Grid**: Built-in search, filter, sort, paging, and toolbar capabilities +- **Complete CRUD Operations**: Add, edit, delete, and batch update records directly from the grid +- **Repository Pattern**: Clean separation of concerns with dependency injection support +- **CustomAdaptor**: Full control over grid data operations (read, search, filter, sort, page) +- **ASP.NET Core Web API**: RESTful backend service with proper CORS configuration +- **Configurable Connection String**: Database credentials managed via **appsettings.json** + +## Prerequisites + +| Component | Version | Purpose | +|-----------|---------|---------| +| Visual Studio 2022 | 17.0 or later | Development IDE with React and ASP.NET Core workload | +| .NET SDK | .NET 10.0 or later | Runtime and build tools for backend API | +| Node.js | 18.x or later | JavaScript runtime for React development | +| npm | 11.x or later | Package manager | +| SQL Server | 2019 or later | Database server | +| Dapper | 2.1.66 or later | Lightweight micro-ORM for SQL mapping | +| Microsoft.Data.SqlClient | Latest | SQL Server data provider | +| Syncfusion.EJ2.AspNet.Core | Latest | Backend support for Syncfusion components | +| @syncfusion/ej2-react-grids | Latest | React Grid component | +| @syncfusion/ej2-data | Latest | Data management utilities | + +## Quick Start + +1. **Clone the repository** + ```bash + git clone + cd syncfusion-react-grid-dapper + ``` + +2. **Create the database and table** + + Open SQL Server Management Studio or SQL Server Express and run: + ```sql + -- Create Database if it doesn't exist + IF NOT EXISTS (SELECT 1 FROM sys.databases WHERE name = N'HotelBookingDB') + BEGIN + CREATE DATABASE HotelBookingDB; + END + GO + + USE HotelBookingDB; + GO + + -- Create Rooms table if it doesn't exist + IF NOT EXISTS (SELECT 1 FROM sys.tables WHERE name = N'Rooms' AND schema_id = SCHEMA_ID(N'dbo')) + BEGIN + CREATE TABLE dbo.Rooms ( + Id INT IDENTITY(1,1) PRIMARY KEY, + ReservationId VARCHAR(50) NOT NULL, + GuestName VARCHAR(100) NOT NULL, + GuestEmail VARCHAR(250) NULL, + CheckInDate DATE NOT NULL, + CheckOutDate DATE NULL, + RoomType VARCHAR(100) NULL, + RoomNumber VARCHAR(20) NULL, + AmountPerDay DECIMAL(18,2) NULL, + NoOfDays INT NULL, + TotalAmount DECIMAL(18,2) NULL, + PaymentStatus VARCHAR(50) NOT NULL, + ReservationStatus VARCHAR(50) NOT NULL + ); + END + GO + + -- Insert Sample Data (Optional). + IF NOT EXISTS (SELECT 1 FROM dbo.Rooms WHERE ReservationId IN (N'RES001001', N'RES001002')) + BEGIN + INSERT INTO dbo.Rooms + (ReservationId, GuestName, GuestEmail, CheckInDate, CheckOutDate, RoomType, RoomNumber, AmountPerDay, NoOfDays, TotalAmount, PaymentStatus, ReservationStatus) + VALUES + (N'RES001001', N'John Doe', N'john.doe@example.com', '2026-01-13', '2026-01-15', N'Deluxe Suite', N'D-204', 150.00, 2, 300.00, N'Paid', N'Confirmed'), + (N'RES001002', N'Mary Smith', N'mary.smith@example.com', '2026-01-14', '2026-01-17', N'Standard Room', N'S-108', 90.00, 3, 270.00, N'Pending', N'Confirmed'); + END + GO + ``` + +3. **Update the connection string** + + Open **Grid_Dapper.Server/appsettings.json** and configure the SQL Server connection: + ```json + { + "Logging": { + "LogLevel": { + "Default": "Information", + "Microsoft.AspNetCore": "Warning" + } + }, + "AllowedHosts": "*", + "ConnectionStrings": { + "HotelBookingDB": "Server=(localdb)\\MSSQLLocalDB;Database=HotelBookingDB;Trusted_Connection=True;TrustServerCertificate=True;" + } + } + ``` + +4. **Install server dependencies and run the API** + + ```bash + cd Grid_Dapper.Server + dotnet build + dotnet run + ``` + The API will run at `https://localhost:7225` (or the port shown in terminal). + +5. **Install client dependencies and run the React app** + + Open a new terminal: + ```bash + cd grid_dapper.client + npm install + npm run dev + ``` + +6. **Open the application** + + Navigate to the local URL displayed in the terminal (typically `http://localhost:5173`). + +## Configuration + +### Connection String + +The connection string in **appsettings.json** contains the following components: + +| Component | Description | Example | +|-----------|-------------|---------| +| Server | SQL Server instance address | `localhost` or `.\SQLEXPRESS` | +| Database | Database name | `HotelBookingDB` | +| Trusted_Connection | Windows Authentication | `True` (for local development) | +| TrustServerCertificate | Certificate validation | `True` (for local development) | + +**Security Note**: For production environments, store sensitive credentials using: +- User secrets for development +- Environment variables for production +- Azure Key Vault or similar secure storage solutions + +For SQL Server Authentication (username/password): +``` +Server=your-server;Database=HotelBookingDB;User ID=sa;Password=;TrustServerCertificate=True +``` + +### API Base URL + +The React client connects to the API server. Update the `BASE_URL` in **grid_dapper.client/src/App.tsx** if your API runs on a different port: + +```typescript +const BASE_URL = 'https://localhost:7225/api/rooms'; +``` + +## Project Layout + +| File/Folder | Purpose | +|-------------|---------| +| **Backend (Grid_Dapper.Server)** | | +| `/Data/Reservation.cs` | Entity model representing the Rooms table | +| `/Data/ReservationRepository.cs` | Repository class providing CRUD methods using Dapper | +| `/Controllers/RoomsController.cs` | ASP.NET Core Web API controller handling HTTP requests | +| `/Program.cs` | Service registration, CORS configuration, and app setup | +| `/appsettings.json` | Application configuration including connection string | +| **Frontend (grid_dapper.client)** | | +| `/src/App.tsx` | Main React component with Grid configuration | +| `/src/CustomAdaptor.ts` | Custom data adaptor for handling grid operations | +| `/src/index.css` | Global CSS styles including Syncfusion theme imports | +| `/src/main.tsx` | React application entry point | +| `/package.json` | NPM dependencies and scripts | +| `/vite.config.ts` | Vite build configuration | + +## Common Tasks + +### Add a Reservation +1. Click the **Add** button in the grid toolbar +2. Fill in the form fields (Guest Name, Email, Check-In Date, Room Type, etc.) +3. Click **Save** to persist the record to the database + +### Edit a Reservation +1. Select a row in the grid +2. Click the **Edit** button in the toolbar (or double-click the row) +3. Modify the required fields +4. Click **Update** to save changes + +### Delete a Reservation +1. Select a row in the grid +2. Click the **Delete** button in the toolbar +3. Confirm the deletion in the dialog + +### Search Records +1. Use the **Search** box in the toolbar +2. Enter keywords to filter records (searches across configured columns) + +### Filter Records +1. Click the filter icon in any column header +2. Select filter criteria (equals, contains, greater than, etc.) +3. Click **Filter** to apply + +### Sort Records +1. Click the column header to sort ascending +2. Click again to sort descending +3. Hold **Shift** and click another column for multi-column sorting + +## Architecture Overview + +### Backend Flow + +1. **Client Request**: React Grid (via CustomAdaptor) sends HTTP POST requests to `/api/rooms` endpoints +2. **Controller**: `RoomsController` receives the request and extracts `DataManagerRequest` parameters +3. **Repository**: `ReservationRepository` uses Dapper to execute parameterized SQL queries +4. **Database**: SQL Server processes the query and returns results +5. **Response**: Data flows back through repository → controller → HTTP response → CustomAdaptor → Grid + +### CustomAdaptor + +The `CustomAdaptor` extends Syncfusion's `UrlAdaptor` and handles: +- **Read operations**: GET with query parameters for filtering, sorting, paging +- **CRUD operations**: POST requests for insert/update/delete +- **Batch operations**: Handles multiple changes in a single request +- **Response transformation**: Processes server responses into Grid-compatible format + +### Repository Pattern with Dapper + +Dapper extension methods used in the repository: + +| Method | Description | +|--------|-------------| +| `QueryAsync` | Executes SELECT queries and maps results to `IEnumerable` | +| `ExecuteScalarAsync` | Executes queries and returns a single scalar value (e.g., new ID) | +| `ExecuteAsync` | Executes INSERT/UPDATE/DELETE and returns affected row count | + +## Troubleshooting + +### Connection Error +- Verify SQL Server is running and accessible on the specified host +- Confirm the database name and authentication method are correct +- For Windows Authentication, ensure user account has access to SQL Server +- For SQL Server Authentication, verify the username and password +- Ensure the `HotelBookingDB` database exists + +### Missing Tables +- Verify the SQL script was executed successfully in SQL Server Management Studio +- Run the database creation script again +- Confirm the table name is `[dbo].[Rooms]` with correct schema + +### CORS Issues +- Verify CORS is configured in `Program.cs` with `app.UseCors()` +- Check that the policy allows the client origin +- Clear browser cache and restart both server and client + +### Grid Not Loading Data +- Check browser console for errors +- Verify the API is running and accessible at the configured URL +- Test the API endpoint directly using Postman or browser +- Ensure the `CustomAdaptor` is correctly configured in `App.tsx` + +### Dapper Mapping Issues +- Ensure column names in the SQL query match the `Reservation` model property names +- Dapper mapping is case-insensitive by default but type-sensitive +- Use column aliases if database column names differ from model properties + +### Version Conflicts +- Align Dapper, Microsoft.Data.SqlClient, and Syncfusion package versions +- Run `dotnet restore` for server and `npm install` for client to update packages +- Check `package.json` and `.csproj` files for conflicting version constraints + +## Reference +The [user guide](https://ej2.syncfusion.com/react/documentation/grid/connecting-to-orm/dapper) provides detailed directions in a clear, step-by-step format. + +# Steps to download GitHub samples using DownGit + +1. **Open the DownGit Website** + + Go to the official DownGit tool: https://downgit.github.io/#/home + +2. **Copy the GitHub URL** + + - Navigate to the sample folder you want to download and copy its URL. + - Example : https://github.com/SyncfusionExamples/ej2-react-grid-samples/tree/master/connecting-to-database/syncfusion-react-grid-dapper + +3. **Paste the URL into DownGit** + + In the DownGit input box, paste the copied GitHub URL. + +4. **Download the ZIP** + + - Click **Download**. + - DownGit will generate a ZIP file of the selected folder, which you can save and extract locally. \ No newline at end of file