Hey guys, I am Venkat and this is part 19 of web development with Blazor video series. In
this video we'll discuss how to implement all the CRUD operations, that is create, read,
update and delete in asp.net core Blazor. In our previous video, part 18 we discussed how to
enable support for CRUD operations in a data grid. Please watch that video before proceeding. Now,
if you recollect from our previous video in this series, on this DataGrid we made three changes to
enable CRUD operations, and here is the first change, we need to tell this DataGrid, among these
columns which column is the primary key column, in our case EmployeeId is the primary key column,
and to specify that on this we have set IsPrimary key equals true,
and here is the second change, we included this component with these three
properties - AllowAdding, AllowEditing and AllowDeleting, and the third change is here,
at the data grid level we have set Toolbar property to a new string array with these strings
in it - Add, Edit, Update etc. So, at this point if we take a look at this page in the browser,
notice we have a toolbar with these buttons - Add, Edit, Update etc, and in the footer
we can see at the moment in the underlying database table we have 33 rows. Now, let's
add a new row by clicking this button and provide a value for first and last name, date of birth
department, gender and email and then before we click update button, let's take a look at visual
studio output window, so in the output window, make sure you have your web server selected,
and at the moment we can see, we only have two SELECT queries, first select query and
second select query. Now, let's click the update button and then let's also try to
edit this second row let's set first and last name to john1 and hastings1, click the update button,
and let's also delete this third row, select the row, click the delete button.
Now, it looks like all these three operations insert, update and delete have been performed,
if we take a look at visual studio output window, again notice we only have those two
SELECT queries, we don't have any of the insert, update or delete SQL statements. This means,
all these operations are performed only at the data grid level, they are not persisted
to the database table, we can prove that very easily by reloading this web page.
Notice everything is reverted back, we still have 33 employees in the data grid table and we have
included 1 in john's first and last name and we have deleted this sam's record, but all these
are reverted back, so what we really want to do is save these changes in the underlying database
table, so let's look at the steps required for that. To be able to save the changes that we make
at the data grid level in the underlying database table we need to handle grid events and for that
we include this component and the even that we want to handle is OnActionBegin
and then let's specify the event handler name as ActionBeginHandler, obviously we can give it any
meaningful name we want, we don't have this even handler method yet, we'll create it in just a bit,
and we also have to tell this component the type of object the grid is working with, in our case
we know it is Employee object. Our obvious next step is to include this event handler,
let's do that in the code block at the bottom right here, public async void, the name of the
method, and this method is going to receive a parameter of type ActionEventArgs,
let's call the parameter Args. Now, here's the important bit to keep in mind, on the data grid
when we perform any of the operations like add, edit, update etc, we know this event OnActionegin
is raised and this is the even handler method, so in the even handler we have to identify the type
of CRUD operation that is being performed, and for that you can use this incoming arguments parameter
if Args.RequestType.Equals( Syncfusion
.Blazor.Grids.Action. we can see all the actions like Save, Add etc, so let's identify if it is the
Save action, what is being saved, is it the Add operation or the Edit operation, again for that,
on the incoming arguments parameter, we have action, if it is equal to add, then we know it is
the add operation, in the data grid when we add a new employee row and then click the update button,
what we really want to do is add that employee in the underlying Employees database table, and for
that we can use this injected EmployeeService, on the EmployeeService we have AddEmployee() method
and obviously to this method we need to pass the employee object that we have added in the
data grid, and to get that employee object we can use this incoming Args parameter, on that we have
Data property and again from the intellisense, you can see it returns us the employee object,
else on the EmployeeService we want to call UpdateEmployee() method.
Just like how we are checking if the request type is Save, by the way if we go to the definition
on this, we can see all the request types here. Now what we want to do is, check if the request
type is delete, and for that same idea, an if condition similar to this what we already have
on line number 58. So if the request type is delete then you want to call DeleteEmployee()
method on our EmployeeService. Now, if we take a look at this EmployeeService,
by the way this EmployeeService is present in the client project in the Services folder right here.
So if we take a look at AddEmployee() method, notice we don't have the implementation,
so let's provide it. Create a variable, let's call it response and on the injected HttpClient
just like how we have GetFromJsonAsync() method, we also have PostAsJsonAsync(),
why PostAsJsonAsync()? well that's because we are creating a new employee and for that we use
the post method, specify the rest api endpoint we want to post to, we know it is /api/employees and
pass the incoming employee object. From the return type we can see we want this method to return the
newly added employee, so for that, return await, on the response object we have Content property,
and on that we use ReadFromJsonAsync() and we want to type cast the json to Employee object,
and we are using the await keyword here, so let's also turn this method
into async. Along the same lines let's provide implementation for DeleteEmployee() method.
Same idea, on the injected HttpClient we're using DeleteAsync() and here is the uri api/employees,
and in the URI, we have to pass the id of the employee that we are deleting. Since we are
using await keyword, let's turn this method also into async. Finally UpdateEmployee()
Same idea, the only difference is, on the injected HttpClient
we use PutASJsonAsync(), why? because we are issuing an update. Again you're
using await keyword, so you know the drill, convert the method to async.
There we go, we have the data displayed as expected. Let's edit this first employee row,
include 1 in both the first and last name, let's change the date of birth to first of august,
department to payroll, gender to female and include 1 again in the email and then, before
we click the update button, let's clear everything that we have in the output window, and then click
the update button. Looks like the employee row is updated, so if we take another look
at visual studio output window, notice we have a parameterized sql update statement here, and we
can confirm the data is updated in the underlying database by reloading this web page. Notice the
first employee row, we have the changes persisted and we can double confirm this by issuing a select
query to our database table. Take a look at this first row, data updated as expected. Next,
let's try out the delete operation. First, take a look at the data grid footer, we have 33 items.
Let's delete this employee row, so we select the row and click the delete button. Before we do
that, as usual let's clear everything that we have in visual studio output window, and then click the
delete button. Looks like the row is deleted, we can see that in the data grid footer here, and
if we take a look at visual studio output window, notice we have a delete sql statement right here,
and we can confirm the record is deleted again by issuing our select query, notice at the bottom
right here, we have 33 rows, so let's execute the select query, now 32 rows. Finally, let's try
add operation. Provide values for first and last name, date of birth, department, gender and email,
and before we click update button, let's clear the output window and then click update.
Looks like the insert operation has succeeded, but we can say something is not quite right
because the employee id value is zero, we'll get to this in just a bit, and if we take a look at
the output window in visual studio, we can see a parameterized sql insert statement here, so we
can be sure the row is inserted into the database table, but then if we take a look at the data grid
footer, notice at the moment we've got 33 items in the grid, now let's see what's going to happen
when we reload this page, notice the footer, 32 items, one item reduced, that's a bit weird, we'll
come to that in just a bit. Let's quickly verify the number of rows that we have in the database
table, notice in the messages tab we can see we have 33 rows and if we scroll all the way down,
we can see our newly inserted row here, and the data is also correct for all these columns
first name, last name, email, date of birth, gender, notice department id, this is taking
the default integer value which is zero. It did not take the department that we have selected in
the drop down list, and that's because of a bug that we have in EmployeeRepository,
and the employee repository file is present in the models folder, so let's open this
and if we take a look at the AddEmployee() method, the bug that we have is because of this if block.
If employee.department is not equal to null, we are basically setting employee.department entity
state to unchanged, so this is not allowing us to use the department that we have selected in the
drop down list. So, to fix it, I'm going to change this code. if employee.departmentId is equal to 0,
that means the end user did not provide a valid department id, so let's throw a new exception
and the exception message is, employee department id cannot be zero, else
we want to check if a valid department id is provided, and for that we need to inject
DepartmentRepository, so let's include a private read-only field,
we need a constructor parameter of the same type, so let's copy and paste this
and then this.departmentRepository equals the constructor parameter
and then in the else block, let's create a variable of type department,
let's call it department, on the injected DepartmentRepository, we have GetDepartment()
method, to it let's pass the employee department id, if the department variable is equal to null,
that means an invalid department id is provided, so let's throw a new exception with the message
invalid employee department id, and to make debugging easier, let's also include
that invalid department id in the message. On the other hand, if this variable is not null,
that means a valid department is provided, so let's set the employee department to the variable
Now, before we try the add operation, let's clean up invalid data that we have in the
Employees database table, take a look at this last row with employee id 59,
we have department id 0 which is invalid, so let's delete this row. Here's the query for that,
execute it, row deleted. Let's select the data,
at the moment we have 32 rows. Now, try the add operation. Provide values for first and last name,
department, payroll, gender female, t@t.com, click update. Looks like the row is inserted,
but still the employee id value is zero, let's select the data from the database table,
notice we have 33 rows now, and if we scroll all the way to the bottom we have our new employee
row, and notice, the department id is correctly stored as expected, but why the id value is still
0 here? well, that's because, after the insert operation, we are not reloading the data and
refreshing the grid, so let's do that now. In our GridEdit razor component, after we add the new
employee row, we want to reload data from the server and populate this Employees property, why
do we need to populate this Employees property? well, that's because it is this Employees property
that our grid is binding to, and we already have code for that in OnInitializedAsync() method,
so let's copy this line and paste it right here. After we reload the data, we also
want to refresh the data grid, and for that we need a property that references the data grid,
so let's create a property of type SfGrid and we know the grid is working with Employee objects,
and let's call this property employeeGrid, and then on the grid itself, we include @ref
and then specify our property there, and then in this if block here, after the data is reloaded,
on the employeeGrid, we call Refresh() method which refreshes the data grid.
Let's try add operation again, we have a small problem here,
when adding a new employee row, there's no need to supply a value for EmployeeId column,
why? Well, Id column is an identity column in the database, this means when a new row is inserted,
the database engine will automatically provide a value for this column, so it makes sense
to keep this column disabled in the data grid, and it's very easy to do.
On the respective grid column, in our case on employee id column, set AllowAdding equals false
Try add operation again, Id column disabled as expected,
let's provide test values for all these columns.
Click update. Notice the data grid footer, the number of rows are updated as expected,
and if we go to the last page, we have our new test row there and we can reconfirm this
by executing select query on our database table, and if we scroll all the way to the end,
we can see our new row here. That's it in this video. Thank you for listening.