Saturday, November 30, 2019

Combine SQL-DB And MongoDB In Same Blazor App

Blazor is a new framework built by Microsoft for creating interactive client-side web UI with .NET codebase. We can write both client-side and server-side code in C#.NET itself. I have already written two articles about Blazor server on C# Corner. Please refer to below articles for more basics about Blazor framework.
Traditionally, in monolithic applications, we are using single database server for entire application. But I am combining SQL database and MongoDB in same application. This application will be a combination of RDBMS and No SQL databases. We will create a Blazor app from scratch and create a SQL database and a table using data migration. We will use this SQL DB to save employee data. We will use MongoDB database to save City data. You can use the same approach for other .NET Core 3.0 applications also. We can see all the actions step by step.

Prerequisites

  • Visual Studio 2019 (version 16.3 or later)
  • .NET Core SDK 3.0
  • MongoDB Server

Create a Blazor application in Visual Studio 2019


We can create a Blazor app in Visual Studio 2019 using Blazor server template.
 
 
We must install below libraries to our project. We can use NuGet to install these libraries.
  • “Microsoft.EntityFrameworkCore.SqlServer”
  • “Microsoft.EntityFrameworkCore.Tools”
  • “MongoDB.Driver”
We can create an “Employee” class inside the “Data” folder with below properties.
 
Employee.cs
  1. namespace BlazorSQLAndMongoDB.Data  
  2. {  
  3.     public class Employee  
  4.     {  
  5.         public string Id { getset; }  
  6.         public string Name { getset; }  
  7.         public string Department { getset; }  
  8.         public string Designation { getset; }  
  9.         public string Company { getset; }  
  10.         public string City { getset; }  
  11.     }  
  12. }  
We can create a “SqlDbContext” class inside the Data folder for entity framework related operations.
 
SqlDbContext.cs
  1. using Microsoft.EntityFrameworkCore;  
  2.   
  3. namespace BlazorSQLAndMongoDB.Data  
  4. {  
  5.     public class SqlDbContext : DbContext  
  6.     {  
  7.         public SqlDbContext(DbContextOptions<SqlDbContext> options)  
  8.            : base(options)  
  9.         {  
  10.         }  
  11.         public DbSet<Employee> Employees { getset; }  
  12.     }  
  13. }  
We can create a connection string in “appsettings.json” for SQL database.
 
 
We have used local SQL server, which is available with Visual Studio to create database and table. You can use any SQL server as per your convenience.
We must register SqlDbContext class inside the “ConfigureServices” method in Startup class.
 

Create SQL database and table using entity framework and data migration


We can use NuGet Package Manager Console from Tools menu and use below migration commands to create SQL database and table.
 
add-migration Initial
 
Above command will create a migration script class inside the “Migrations” folder with current timestamp suffix.
 
We can use below command to create database and table.
 
update-database
 
Database and table will be created shortly.
 
We can create an “IEmployeeService“ interface and declare below methods inside the interface.
 
IEmployeeService.cs
  1. using System.Collections.Generic;  
  2. using System.Threading.Tasks;  
  3.   
  4. namespace BlazorSQLAndMongoDB.Data  
  5. {  
  6.     public interface IEmployeeService  
  7.     {  
  8.         Task<List<Employee>> GetEmployees();  
  9.         Task<bool> CreateEmployee(Employee employee);  
  10.         Task<bool> EditEmployee(string id, Employee employee);  
  11.         Task<Employee> SingleEmployee(string id);  
  12.         Task<bool> DeleteEmployee(string id);  
  13.     }  
  14. }  
We can implement above methods from the interface in another class “EmployeeService”
 
EmployeeService.cs
  1. using Microsoft.EntityFrameworkCore;  
  2. using System;  
  3. using System.Collections.Generic;  
  4. using System.Threading.Tasks;  
  5.   
  6. namespace BlazorSQLAndMongoDB.Data  
  7. {  
  8.     public class EmployeeService : IEmployeeService  
  9.     {  
  10.         private readonly SqlDbContext _dbContext;  
  11.   
  12.         public EmployeeService(SqlDbContext dbContext)  
  13.         {  
  14.             _dbContext = dbContext;  
  15.         }  
  16.         public async Task<List<Employee>> GetEmployees()  
  17.         {  
  18.             return await _dbContext.Employees.ToListAsync();  
  19.         }  
  20.         public async Task<bool> CreateEmployee(Employee employee)  
  21.         {  
  22.             employee.Id = Guid.NewGuid().ToString();  
  23.             _dbContext.Add(employee);  
  24.             try  
  25.             {  
  26.                 await _dbContext.SaveChangesAsync();  
  27.                 return true;  
  28.             }  
  29.             catch (DbUpdateException)  
  30.             {  
  31.                 return false;  
  32.             }  
  33.   
  34.         }  
  35.         public async Task<Employee> SingleEmployee(string id)  
  36.         {  
  37.             return await _dbContext.Employees.FindAsync(id);  
  38.         }  
  39.         public async Task<bool> EditEmployee(string id, Employee employee)  
  40.         {  
  41.             if (id != employee.Id)  
  42.             {  
  43.                 return false;  
  44.             }  
  45.   
  46.             _dbContext.Entry(employee).State = EntityState.Modified;  
  47.             await _dbContext.SaveChangesAsync();  
  48.             return true;  
  49.         }  
  50.         public async Task<bool> DeleteEmployee(string id)  
  51.         {  
  52.             var patient = await _dbContext.Employees.FindAsync(id);  
  53.             if (patient == null)  
  54.             {  
  55.                 return false;  
  56.             }  
  57.   
  58.             _dbContext.Employees.Remove(patient);  
  59.             await _dbContext.SaveChangesAsync();  
  60.             return true;  
  61.         }  
  62.     }  
  63. }  
We have added all logic for CRUD operations inside the service class. Please note that, you can even create this service without an interface.
 
We can create a City class with below properties. City data will be stored in MongoDB.
 
City.cs
  1. using MongoDB.Bson;  
  2. using MongoDB.Bson.Serialization.Attributes;  
  3.   
  4. namespace BlazorSQLAndMongoDB.Data  
  5. {  
  6.     public class City  
  7.     {  
  8.         [BsonId]  
  9.         [BsonRepresentation(BsonType.ObjectId)]  
  10.         public string Id { getset; }  
  11.         public string Name { getset; }  
  12.         public string State { getset; }  
  13.     }  
  14. }  
We can keep MongoDB connection string, database name, and collection name inside the appsettings.json file instead of hard coding the values.
 
 
We must create an interface and class for reading the values from appsettings.json file.
 
We can create “IMongoDbSettings” interface and declare below properties.
 
IMongoDbSettings.cs
  1. namespace BlazorSQLAndMongoDB.Data  
  2. {  
  3.     public interface IMongoDbSettings  
  4.     {  
  5.         string CollectionName { getset; }  
  6.         string ConnectionString { getset; }  
  7.         string DatabaseName { getset; }  
  8.     }  
  9. }  
We can create “MongoDbSettings” class and inherit IMongoDbSettings interface inside the class.
 
MongoDbSettings.cs
  1. namespace BlazorSQLAndMongoDB.Data  
  2. {  
  3.     public class MongoDbSettings : IMongoDbSettings  
  4.     {  
  5.         public string CollectionName { getset; }  
  6.         public string ConnectionString { getset; }  
  7.         public string DatabaseName { getset; }  
  8.     }  
  9. }  
We can register this interface and class inside the ConfigureServices class in Startup class.
 
 
 
We can create an “ICityService“ interface and declare below methods inside the interface.
 
ICityService.cs
  1. using System.Collections.Generic;  
  2. using System.Threading.Tasks;  
  3.   
  4. namespace BlazorSQLAndMongoDB.Data  
  5. {  
  6.     public interface ICityService  
  7.     {  
  8.         Task<List<City>> GetCities();  
  9.         Task<bool> CreateCity(City city);  
  10.         Task<bool> EditCity(string id, City city);  
  11.         Task<City> SingleCity(string id);  
  12.         Task<bool> DeleteCity(string id);  
  13.     }  
  14. }  
We can implement above methods from the interface in another class “CityService”
 
CityService.cs
  1. using MongoDB.Driver;  
  2. using System.Collections.Generic;  
  3. using System.Threading.Tasks;  
  4.   
  5. namespace BlazorSQLAndMongoDB.Data  
  6. {  
  7.     public class CityService : ICityService  
  8.     {  
  9.         private readonly IMongoCollection<City> _cities;  
  10.         public CityService(IMongoDbSettings settings)  
  11.         {  
  12.             var client = new MongoClient(settings.ConnectionString);  
  13.             var database = client.GetDatabase(settings.DatabaseName);  
  14.   
  15.             _cities = database.GetCollection<City>(settings.CollectionName);  
  16.         }  
  17.         public async Task<bool> CreateCity(City city)  
  18.         {  
  19.             try  
  20.             {  
  21.                 await _cities.InsertOneAsync(city);  
  22.                 return true;  
  23.             }  
  24.             catch  
  25.             {  
  26.                 return false;  
  27.             }  
  28.         }  
  29.   
  30.         public async Task<bool> DeleteCity(string id)  
  31.         {  
  32.             try  
  33.             {  
  34.                 await _cities.DeleteOneAsync(book => book.Id == id);  
  35.                 return true;  
  36.             }  
  37.             catch  
  38.             {  
  39.                 return false;  
  40.             }  
  41.         }  
  42.   
  43.         public async Task<bool> EditCity(string id, City city)  
  44.         {  
  45.             try  
  46.             {  
  47.                 await _cities.ReplaceOneAsync(book => book.Id == id, city);  
  48.                 return true;  
  49.             }  
  50.             catch  
  51.             {  
  52.                 return false;  
  53.             }  
  54.         }  
  55.   
  56.         public async Task<List<City>> GetCities()  
  57.         {  
  58.             try  
  59.             {  
  60.                 return await _cities.Find(city => true).ToListAsync();  
  61.             }  
  62.             catch  
  63.             {  
  64.                 return null;  
  65.             }  
  66.         }  
  67.   
  68.         public async Task<City> SingleCity(string id)  
  69.         {  
  70.             try  
  71.             {  
  72.                 return await _cities.Find<City>(city => city.Id == id).FirstOrDefaultAsync();  
  73.             }  
  74.             catch  
  75.             {  
  76.                 return null;  
  77.             }  
  78.         }  
  79.     }  
  80. }  
We have injected the IMongoDbSettings interface in above class and fetched MongoDB configuration values from appsettings.json file.
 
We have added all logic for CRUD actions for City entity inside the above service class.
 
We can register both Employee service and City service in the Startup class.
 
 
 
We can enable detailed circuit errors for Blazor server application also in startup class.
 
ConfigureServices (method)
  1. public void ConfigureServices(IServiceCollection services)  
  2.         {  
  3.             services.AddRazorPages();  
  4.             services.AddServerSideBlazor();  
  5.             services.AddSingleton<WeatherForecastService>();  
  6.   
  7.             services.AddDbContext<SqlDbContext>(options =>  
  8.                    options.UseSqlServer(Configuration.GetConnectionString("SqlDbContext")));  
  9.   
  10.             services.Configure<MongoDbSettings>(Configuration.GetSection(nameof(MongoDbSettings)));  
  11.             services.AddSingleton<IMongoDbSettings>(sp => sp.GetRequiredService<IOptions<MongoDbSettings>>().Value);  
  12.   
  13.             services.AddScoped<IEmployeeService, EmployeeService>();  
  14.             services.AddScoped<ICityService, CityService>();  
  15.   
  16.             services.AddServerSideBlazor().AddCircuitOptions(o => o.DetailedErrors = true);  
  17.         }  
We have completed the backend part of Blazor application. We can create all razor components inside “Pages” folder for CRUD operations.
 
We can create components for City first.
 
ListCities.razor
  1. @using BlazorSQLAndMongoDB.Data  
  2.   
  3. @page "/listcities"  
  4. @inject ICityService CityService  
  5.   
  6. <h2>City Details</h2>  
  7. <p>  
  8.     <a href="/addcity">Create New City</a>  
  9. </p>  
  10.   
  11. @if (cities == null)  
  12. {  
  13.     <img src="./basicloader.gif" />  
  14. }  
  15. else  
  16. {  
  17.     <table class='table'>  
  18.         <thead>  
  19.             <tr>  
  20.                 <th>Name</th>  
  21.                 <th>State</th>  
  22.             </tr>  
  23.         </thead>  
  24.         <tbody>  
  25.             @foreach (var city in cities)  
  26.             {  
  27.                 <tr>  
  28.                     <td>@city.Name</td>  
  29.                     <td>@city.State</td>  
  30.                     <td>  
  31.                         <a href='/editcity/@city.Id'>Edit</a>  
  32.                         <a href='/deletecity/@city.Id'>Delete</a>  
  33.                     </td>  
  34.                 </tr>  
  35.   
  36.             }  
  37.         </tbody>  
  38.     </table>  
  39. }  
  40.   
  41. @code {  
  42.     List<City> cities;  
  43.   
  44.     protected override async Task OnInitializedAsync()  
  45.     {  
  46.         cities = await CityService.GetCities();  
  47.     }  
  48. }     
AddCity.razor
  1. @using BlazorSQLAndMongoDB.Data  
  2.   
  3. @page "/addcity"  
  4. @inject NavigationManager NavigationManager  
  5. @inject ICityService CityService  
  6.   
  7. <h2>Create City</h2>  
  8. <hr />  
  9. <form>  
  10.     <div class="row">  
  11.         <div class="col-md-8">  
  12.             <div class="form-group">  
  13.                 <label for="Name" class="control-label">Name</label>  
  14.                 <input for="Name" class="form-control" @bind="@city.Name" />  
  15.             </div>  
  16.             <div class="form-group">  
  17.                 <label for="State" class="control-label">State</label>  
  18.                 <input for="State" class="form-control" @bind="@city.State" />  
  19.             </div>  
  20.         </div>  
  21.     </div>  
  22.     <div class="row">  
  23.         <div class="col-md-4">  
  24.             <div class="form-group">  
  25.                 <input type="button" class="btn btn-primary" @onclick="@CreateCity" value="Save" />  
  26.                 <input type="button" class="btn" @onclick="@Cancel" value="Cancel" />  
  27.             </div>  
  28.         </div>  
  29.     </div>  
  30. </form>  
  31.   
  32. @code {  
  33.   
  34.     City city = new City();  
  35.   
  36.     protected async Task CreateCity()  
  37.     {  
  38.         await CityService.CreateCity(city);  
  39.         NavigationManager.NavigateTo("listcities");  
  40.     }  
  41.   
  42.     void Cancel()  
  43.     {  
  44.         NavigationManager.NavigateTo("listcities");  
  45.     }  
  46. }     
EditCity.razor
  1. @using BlazorSQLAndMongoDB.Data  
  2.   
  3. @page "/editcity/{id}"  
  4. @inject NavigationManager NavigationManager  
  5. @inject ICityService CityService  
  6.   
  7. <h2>Edit City</h2>  
  8. <hr />  
  9. <form>  
  10.     <div class="row">  
  11.         <div class="col-md-8">  
  12.             <div class="form-group">  
  13.                 <label for="Name" class="control-label">Name</label>  
  14.                 <input for="Name" class="form-control" @bind="@city.Name" />  
  15.             </div>  
  16.             <div class="form-group">  
  17.                 <label for="State" class="control-label">State</label>  
  18.                 <input for="State" class="form-control" @bind="@city.State" />  
  19.             </div>  
  20.         </div>  
  21.     </div>  
  22.     <div class="row">  
  23.         <div class="form-group">  
  24.             <input type="button" class="btn btn-primary" @onclick="@UpdateCity" value="Update" />  
  25.             <input type="button" class="btn" @onclick="@Cancel" value="Cancel" />  
  26.         </div>  
  27.     </div>  
  28. </form>  
  29.   
  30. @code {  
  31.   
  32.     [Parameter]  
  33.     public string id { getset; }  
  34.   
  35.     City city = new City();  
  36.   
  37.     protected override async Task OnInitializedAsync()  
  38.     {  
  39.         city = await CityService.SingleCity(id);  
  40.     }  
  41.   
  42.     protected async Task UpdateCity()  
  43.     {  
  44.         await CityService.EditCity(id, city);  
  45.         NavigationManager.NavigateTo("listcities");  
  46.     }  
  47.   
  48.     void Cancel()  
  49.     {  
  50.         NavigationManager.NavigateTo("listcities");  
  51.     }  
  52. }     
DeleteCity.razor
  1. @using BlazorSQLAndMongoDB.Data  
  2.   
  3. @page "/deletecity/{id}"  
  4. @inject NavigationManager NavigationManager  
  5. @inject ICityService CityService  
  6.   
  7. <h2>Confirm Delete</h2>  
  8. <p>Are you sure you want to delete this City with Id :<b> @id</b></p>  
  9. <br />  
  10. <div class="col-md-4">  
  11.     <table class="table">  
  12.         <tr>  
  13.             <td>Name</td>  
  14.             <td>@city.Name</td>  
  15.         </tr>  
  16.         <tr>  
  17.             <td>State</td>  
  18.             <td>@city.State</td>  
  19.         </tr>  
  20.     </table>  
  21.     <div class="form-group">  
  22.         <input type="button" value="Delete" @onclick="@Delete" class="btn btn-primary" />  
  23.         <input type="button" value="Cancel" @onclick="@Cancel" class="btn" />  
  24.     </div>  
  25. </div>  
  26.   
  27. @code {  
  28.   
  29.     [Parameter]  
  30.     public string id { getset; }  
  31.     City city = new City();  
  32.   
  33.     protected override async Task OnInitializedAsync()  
  34.     {  
  35.         city = await CityService.SingleCity(id);  
  36.     }  
  37.   
  38.     protected async Task Delete()  
  39.     {  
  40.         await CityService.DeleteCity(id);  
  41.         NavigationManager.NavigateTo("listcities");  
  42.     }  
  43.   
  44.     void Cancel()  
  45.     {  
  46.         NavigationManager.NavigateTo("listcities");  
  47.     }  
  48. }     
We can create components for Employee now.
 
ListEmployees.razor
  1. @using BlazorSQLAndMongoDB.Data  
  2.   
  3. @page "/listemployees"  
  4. @inject IEmployeeService EmployeeService  
  5.   
  6. <h2>Employee Details</h2>  
  7. <p>  
  8.     <a href="/addemployee">Create New Employee</a>  
  9. </p>  
  10. @if (employees == null)  
  11. {  
  12.     <img src="./basicloader.gif" />  
  13. }  
  14. else  
  15. {  
  16.     <table class='table'>  
  17.         <thead>  
  18.             <tr>  
  19.                 <th>Name</th>  
  20.                 <th>Department</th>  
  21.                 <th>Designation</th>  
  22.                 <th>Company</th>  
  23.                 <th>City</th>  
  24.             </tr>  
  25.         </thead>  
  26.         <tbody>  
  27.             @foreach (var employee in employees)  
  28.             {  
  29.                 <tr>  
  30.                     <td>@employee.Name</td>  
  31.                     <td>@employee.Department</td>  
  32.                     <td>@employee.Designation</td>  
  33.                     <td>@employee.Company</td>  
  34.                     <td>@employee.City</td>  
  35.                     <td>  
  36.                         <a href='/editemployee/@employee.Id'>Edit</a>  
  37.                         <a href='/deleteemployee/@employee.Id'>Delete</a>  
  38.                     </td>  
  39.                 </tr>  
  40.   
  41.             }  
  42.         </tbody>  
  43.     </table>  
  44. }  
  45.   
  46. @code {  
  47.     List<Employee> employees;  
  48.     
  49.     protected override async Task OnInitializedAsync()  
  50.     {  
  51.         employees = await EmployeeService.GetEmployees();  
  52.     }  
  53. }     
AddEmployee.razor
  1. @using BlazorSQLAndMongoDB.Data  
  2.   
  3. @page "/addemployee"  
  4. @inject NavigationManager NavigationManager  
  5. @inject IEmployeeService EmployeeService  
  6. @inject ICityService CityService  
  7.   
  8. <h2>Create Employee</h2>  
  9. <hr />  
  10. <form>  
  11.     <div class="row">  
  12.         <div class="col-md-8">  
  13.             <div class="form-group">  
  14.                 <label for="Name" class="control-label">Name</label>  
  15.                 <input for="Name" class="form-control" @bind="@employee.Name" />  
  16.             </div>  
  17.             <div class="form-group">  
  18.                 <label for="Department" class="control-label">Department</label>  
  19.                 <input for="Department" class="form-control" @bind="@employee.Department" />  
  20.             </div>  
  21.             <div class="form-group">  
  22.                 <label for="Designation" class="control-label">Designation</label>  
  23.                 <input for="Designation" class="form-control" @bind="@employee.Designation" />  
  24.             </div>  
  25.             <div class="form-group">  
  26.                 <label for="Company" class="control-label">Company</label>  
  27.                 <input for="Company" class="form-control" @bind="@employee.Company" />  
  28.             </div>  
  29.             <div class="form-group">  
  30.                 <label asp-for="City" class="control-label">City</label>  
  31.                 <select asp-for="City" class="form-control" @bind="@employee.City">  
  32.                     <option value="">-- Select City --</option>  
  33.                     @foreach (var city in cities)  
  34.                     {  
  35.                         <option value="@city.Name">@city.Name</option>  
  36.   
  37.                     }  
  38.                 </select>  
  39.             </div>  
  40.         </div>  
  41.     </div>  
  42.     <div class="row">  
  43.         <div class="col-md-4">  
  44.             <div class="form-group">  
  45.                 <input type="button" class="btn btn-primary" @onclick="@CreateEmployee" value="Save" />  
  46.                 <input type="button" class="btn" @onclick="@Cancel" value="Cancel" />  
  47.             </div>  
  48.         </div>  
  49.     </div>  
  50. </form>  
  51.   
  52. @code {  
  53.   
  54.     Employee employee = new Employee();  
  55.     List<City> cities = new List<City>();  
  56.   
  57.     protected override async Task OnInitializedAsync()  
  58.     {  
  59.         cities = await CityService.GetCities();  
  60.     }  
  61.   
  62.     protected async Task CreateEmployee()  
  63.     {  
  64.         await EmployeeService.CreateEmployee(employee);  
  65.         NavigationManager.NavigateTo("listemployees");  
  66.     }  
  67.   
  68.     void Cancel()  
  69.     {  
  70.         NavigationManager.NavigateTo("listemployees");  
  71.     }  
  72. }     
Please note that, I have injected both City service and Employee service in above component. City component is used to fetch city name from MongoDB and Employee service is used to save all employee data in SQL database.
 
EditEmployee.razor
  1. @using BlazorSQLAndMongoDB.Data  
  2.   
  3. @page "/editemployee/{id}"  
  4. @inject NavigationManager NavigationManager  
  5. @inject IEmployeeService EmployeeService  
  6. @inject ICityService CityService  
  7.   
  8. <h2>Edit Employee</h2>  
  9. <hr />  
  10. <form>  
  11.     <div class="row">  
  12.         <div class="col-md-8">  
  13.             <div class="form-group">  
  14.                 <label for="Name" class="control-label">Name</label>  
  15.                 <input for="Name" class="form-control" @bind="@employee.Name" />  
  16.             </div>  
  17.             <div class="form-group">  
  18.                 <label for="Department" class="control-label">Department</label>  
  19.                 <input for="Department" class="form-control" @bind="@employee.Department" />  
  20.             </div>  
  21.             <div class="form-group">  
  22.                 <label for="Designation" class="control-label">Designation</label>  
  23.                 <input for="Designation" class="form-control" @bind="@employee.Designation" />  
  24.             </div>  
  25.             <div class="form-group">  
  26.                 <label for="Company" class="control-label">Company</label>  
  27.                 <input for="Company" class="form-control" @bind="@employee.Company" />  
  28.             </div>  
  29.             <div class="form-group">  
  30.                 <label asp-for="City" class="control-label">City</label>  
  31.                 <select asp-for="City" class="form-control" @bind="@employee.City">  
  32.                     <option value="">-- Select City --</option>  
  33.                     @foreach (var city in cities)  
  34.                     {  
  35.                         <option value="@city.Name">@city.Name</option>  
  36.                     }  
  37.                 </select>  
  38.             </div>  
  39.         </div>  
  40.     </div>  
  41.     <div class="row">  
  42.         <div class="form-group">  
  43.             <input type="button" class="btn btn-primary" @onclick="@UpdateEmployee" value="Update" />  
  44.             <input type="button" class="btn" @onclick="@Cancel" value="Cancel" />  
  45.         </div>  
  46.     </div>  
  47. </form>  
  48.   
  49. @code {  
  50.   
  51.     [Parameter]  
  52.     public string id { getset; }  
  53.   
  54.     Employee employee = new Employee();  
  55.     List<City> cities = new List<City>();  
  56.   
  57.     protected override async Task OnInitializedAsync()  
  58.     {  
  59.         cities = await CityService.GetCities();  
  60.         employee = await EmployeeService.SingleEmployee(id);  
  61.     }  
  62.   
  63.     protected async Task UpdateEmployee()  
  64.     {  
  65.         await EmployeeService.EditEmployee(id, employee);  
  66.         NavigationManager.NavigateTo("listemployees");  
  67.     }  
  68.   
  69.     void Cancel()  
  70.     {  
  71.         NavigationManager.NavigateTo("listemployees");  
  72.     }  
  73. }     
This component is also injected City service and Employee service.
 
DeleteEmployee.razor
  1. @using BlazorSQLAndMongoDB.Data  
  2.   
  3. @page "/deleteemployee/{id}"  
  4. @inject NavigationManager NavigationManager  
  5. @inject IEmployeeService EmployeeService  
  6.   
  7. <h2>Confirm Delete</h2>  
  8. <p>Are you sure you want to delete this Employee with Id :<b> @id</b></p>  
  9. <br />  
  10. <div class="col-md-4">  
  11.     <table class="table">  
  12.         <tr>  
  13.             <td>Name</td>  
  14.             <td>@employee.Name</td>  
  15.         </tr>  
  16.         <tr>  
  17.             <td>Department</td>  
  18.             <td>@employee.Department</td>  
  19.         </tr>  
  20.         <tr>  
  21.             <td>Designation</td>  
  22.             <td>@employee.Designation</td>  
  23.         </tr>  
  24.         <tr>  
  25.             <td>Company</td>  
  26.             <td>@employee.Company</td>  
  27.         </tr>  
  28.         <tr>  
  29.             <td>City</td>  
  30.             <td>@employee.City</td>  
  31.         </tr>  
  32.     </table>  
  33.     <div class="form-group">  
  34.         <input type="button" value="Delete" @onclick="@Delete" class="btn btn-primary" />  
  35.         <input type="button" value="Cancel" @onclick="@Cancel" class="btn" />  
  36.     </div>  
  37. </div>  
  38.   
  39. @code {  
  40.   
  41.     [Parameter]  
  42.     public string id { getset; }  
  43.     Employee employee = new Employee();  
  44.   
  45.     protected override async Task OnInitializedAsync()  
  46.     {  
  47.         employee = await EmployeeService.SingleEmployee(id);  
  48.     }  
  49.   
  50.     protected async Task Delete()  
  51.     {  
  52.         await EmployeeService.DeleteEmployee(id);  
  53.         NavigationManager.NavigateTo("listemployees");  
  54.     }  
  55.   
  56.     void Cancel()  
  57.     {  
  58.         NavigationManager.NavigateTo("listemployees");  
  59.     }  
  60. }     
We can modify the NavMenu shared component to add routing for City and Employee data.
 
NavMenu.razor
  1. <div class="top-row pl-4 navbar navbar-dark">  
  2.     <a class="navbar-brand" href="">Blazor with SQL and Mongo</a>  
  3.     <button class="navbar-toggler" @onclick="ToggleNavMenu">  
  4.         <span class="navbar-toggler-icon"></span>  
  5.     </button>  
  6. </div>  
  7.   
  8. <div class="@NavMenuCssClass" @onclick="ToggleNavMenu">  
  9.     <ul class="nav flex-column">  
  10.         <li class="nav-item px-3">  
  11.             <NavLink class="nav-link" href="" Match="NavLinkMatch.All">  
  12.                 <span class="oi oi-home" aria-hidden="true"></span> Home  
  13.             </NavLink>  
  14.         </li>  
  15.         <li class="nav-item px-3">  
  16.             <NavLink class="nav-link" href="listcities">  
  17.                 <span class="oi oi-plus" aria-hidden="true"></span> City details  
  18.             </NavLink>  
  19.         </li>  
  20.         <li class="nav-item px-3">  
  21.             <NavLink class="nav-link" href="listemployees">  
  22.                 <span class="oi oi-list-rich" aria-hidden="true"></span> Employee details  
  23.             </NavLink>  
  24.         </li>  
  25.     </ul>  
  26. </div>  
  27.   
  28. @code {  
  29.     bool collapseNavMenu = true;  
  30.   
  31.     string NavMenuCssClass => collapseNavMenu ? "collapse" : null;  
  32.   
  33.     void ToggleNavMenu()  
  34.     {  
  35.         collapseNavMenu = !collapseNavMenu;  
  36.     }  
  37. }  
We have removed the routing for Counter and Weather data which are created by default.
 
We have completed the entire coding part. We can run the application. Please make sure your MongoDB windows service is running.
 
 
We can create a new City data.
 
 
 
After saving the data, you can check the MongoDB data using MongoDB compass software.
 
 
 
We can see the newly added City data available there.
 
We can create a new Employee data now.
 
 
 
We can add one more Employee detail and list two Employees details in the grid.
 
 
 
We have successfully added two Cities and two Employees with application.

No comments:

Post a Comment

Lab 09: Publish and subscribe to Event Grid events

  Microsoft Azure user interface Given the dynamic nature of Microsoft cloud tools, you might experience Azure UI changes that occur after t...