Blazor App: From enum properties to SQL tabled properties Part 2
ai database entity-framework csharp blazor
Discussion of the completion of the task of using an AI Coding tool (WindSurf) to modify a Blazor app to replace enum lists with SQL tables. A final solution involved overriding the ToString method in the FK classes to return the Name property, which is called implicitly when the property is used in the UI code. This eliminated the need for additional properties in the dependent entity and provided a cleaner and more maintainable solution. An Admin page has also been added to the Blazor app that allows for adding new locations and competitions directly from the UI, without needing to modify the database manually. It also permits modification and deletion of these entries with appropriate validation and confirmation dialogs.
Later Refinements
The problem all along was when the second approach as above referring directly to the property, that properties rendered in the UI thus:
AthsEssAVHelpers.Data.dbCompetition
AthsEssAVHelpers.Data.Location
The previous version using enums, just literally turned the enum value into a string. The solution was to add a name property for each to the Program class for each of the two properties that uses the values. This forces the property value lookups. It also handles returning “Unknown” when the Id for a property is null. In the Program class. But that was overkill. What was needed was to add a ToString override method to the dbCompetition and Location classes. This is a much more elegant solution. The ToString method is called implicitly when the property is used in the UI code. So, for example, in the FK class:
public override string ToString()
{
if (string.IsNullOrEmpty(Name))
return "Unknown";
return Name;
}
Note the override moniker which is needed to override the default ToString method. Then in the UI code, just use the dbCompetition or Location property directly. Eg:
<GridColumn Field="@(nameof(AVSLProgram.dbCompetition))" Title="Competition" Width="150px" />
When this is rendered, the ToString method for the dbCompetition class is called, which returns the Name property. This is a much cleaner solution than adding additional properties to the Program class. It also means that if we want to use the dbCompetition or Location properties elsewhere in the code, they will automatically return their Name when converted to a string, without needing to add additional properties or logic in the target entity. There is now no need for LocationName and dbCompetitionName properties in the Program class. This is a better and more maintainable solution. 🙂
Side comments
When setting an AI tool “loose” om your code, it is important to have a good repository management strategy. In this case, I had a good strategy of making regular commits to the repository as I made changes. This allowed me to easily revert to a previous commit if something went wrong. It also allowed me to track the changes that were made and understand the history of the code. When using an AI tool, it is also important to review the changes that are made and test them thoroughly before committing them to the repository. This can help catch any issues or bugs that may have been introduced by the AI tool. Overall, having a good repository management strategy is crucial when using AI tools for code development, as it provides a safety net and allows for better tracking and understanding of changes made to the codebase.
Another issue is when making changes to the database schema, it is important to have a good backup strategy in place, starting with a backup of the database elsewhere.. This can help prevent data loss if something goes wrong during the migration process. It is also important to test the changes in a staging environment before applying them to production, to ensure that everything works as expected and that there are no issues with the new schema or data. Additionally, when making changes to the database schema, and data migrations, it is important to consider the impact on existing code and queries that may be using the old schema, and to update them accordingly to avoid any issues or errors. Finally you need to understand how to undo a migration in concert with repository reversions.
Admin Page for adding Locations and Competitions
In the previous post it was stated that a future refinement will be to add an Admin page to the Blazor app that allows for adding new locations and competitions directly from the UI, without needing to modify the database manually. This would provide a more user-friendly way to manage these entities and ensure that the application remains up-to-date with the latest data. Using AI (WindSurf) tool, this was completed quite quickly.
The page now handles complete CRUD. It can now add, edit and delete locations and competitions. It also includes validation to ensure that duplicate entries are not added and that required fields are filled out. This provides a much more robust and user-friendly way to manage the locations and competitions in the application, without needing to directly interact with the database. It also allows for easier maintenance and updates, as new locations and competitions can be added or modified directly from the UI without needing to rebuild or redeploy the app. Finally, it does not permit cascade deletions. If a entry from one of the 2 tables is to be deleted, it checks if it used anywhere as Foreign Key and if true it does not complete the deletion.Overall, this is a significant improvement in terms of usability and maintainability for the application.
The page is protected by an Admin role, so only users with the appropriate permissions can access it. This helps to ensure that only authorized users can make changes to the locations and competitions, which is important for maintaining the integrity of the data and preventing unauthorized modifications. Also, the page does not appear in the NavMenu for non-Admin users.
The page development was quite “clean” starting with an initial specification of requirements. WindSurf returned a largely suitable page but was refined with further specifications wrt functionality and UI layout. The page only took about 5 iterations. The biggest error was to use a MinWidth column specification which was not available for the Telerik Blazor Grid component. This was easily fixed subjugating that to the pages css. The page also includes a confirmation dialog when deleting entries, to prevent accidental deletions.
The buttons on the page were made to conform to some css settings on the page, apart from the color which was controlled by their ThemeColor property, with same theme color applied to same buttons (Add,Edit,Delete). The options here can be viewed at Telerik.Appearance Settings.
<div class="row">
<div class="col-md-12">
<h4>Competitions</h4>
<TelerikGrid Data="@CompetitionsList"
Pageable="true"
PageSize="10"
Sortable="true"
FilterMode="Telerik.Blazor.GridFilterMode.FilterRow"
Resizable="true"
Reorderable="true">
<GridColumns>
<GridColumn Field="@(nameof(dbCompetition.Id))" Title="ID" Width="10px" />
<GridColumn Field="@(nameof(dbCompetition.Name))" Title="Name" Width="50px" />
<GridColumn Field="@(nameof(dbCompetition.IsOther))" Title="Is Other" Width="20px" />
<GridColumn Title="Actions" Width="50px">
<Template Context="competitionContext">
@{
var competition = competitionContext as dbCompetition;
<div class="button-group">
<TelerikButton ButtonType="@ButtonType.Button"
ThemeColor="@ThemeConstants.Button.ThemeColor.Info"
OnClick="@(() => EditCompetition(competition))">Edit</TelerikButton>
<TelerikButton ButtonType="@ButtonType.Button"
ThemeColor="@ThemeConstants.Button.ThemeColor.Error"
OnClick="@(() => DeleteCompetition(competition))">Delete</TelerikButton>
</div>
}
</Template>
</GridColumn>
</GridColumns>
</TelerikGrid>
<br />
<TelerikButton ButtonType="@ButtonType.Button"
ThemeColor="@ThemeConstants.Button.ThemeColor.Success"
OnClick="AddNewCompetition">Add New Competition</TelerikButton>
</div>
</div>
| Topic | Subtopic | |
| This Category Links | ||
| Category: | Artificial Intelligence Index: | Artificial Intelligence |
| < Prev: | Blazor App | From enum properties to SQL tabled properties Part 1 |