Resolving Issues and New Feature in Sights

The past week was occupied by debugging and troubleshooting sessions to ensure the seamless functionality of the sandbox application for the upcoming task. I continued to test the data entry pages for each entity to ensure that they could be saved and edited successfully, building on the work I had done the week before, which involved developing three unique seed generators for various entities. 

However, I encountered an issue with editing one of the entities, which prompted me to dive into another round of debugging in order to identify and resolve the error. Despite spending a considerable amount of time on this, the source of the error remained unresolved Fortunately, later in the day, Mr. Peter aided me. He assessed the error and stated that it may be related to the function I was using. He pointed me in the direction of a different function, one more suited to the seed generator of this specific entity.

The following morning brought a pleasant surprise, as everything operated smoothly without any errors cropping up. In an effort to introduce diversity and practicality to the generated data rather than producing the same type repeatedly I incorporated the use of the Random() function. This allowed the application to select data at random from the available options whenever new seed data was being created.

With the application’s functionality well in hand, Mr. Peter assigned me a fresh task: implementing additional features within an entity’s list page. Specifically, the task involved on unfulfilled orders that had surpassed their fulfillment dates, and granting them the ability to cancel these orders. After the briefing, I comprehended the feature’s concept and proceeded to outline the necessary steps to plan out the execution of the task in the upcoming week.

Emerging Issues with Mapping and Batch Seed Data Generators

Following the successful generation of batch commits as previously discussed, I delved into the primary reason for the creation of the seed generator over the last week. This objective was to facilitate testing of the pages and an entity combo box, employed within a dropdown button. The goal was to monitor the response and ensure the correct appearance of the dropdown button, as well as accurate data display. In line with Mr Peter’s predictions, the button that should have displayed a comprehensive list of entities was not displayed as expected.

To address this, I initiated a debugging phase. My digging eventually led me to the conclusion that the problem could be solved by adjusting the query’s page size limit when invoking the list of entities. Due to my lack of knowledge about setting up an unlimited page size, I initially manually set the page size to display 100,000 entries. Mr. Peter, thankfully, provided guidance, recommending the use of “-1” to indicate an unlimited page size. After getting familiar with this method, the entity successfully transmitted its whole list without issue.

Following that, I discovered another entity within the seed data generator that did not yet have 5000 records. It also revealed a new error that only appeared when attempting to generate over 100 records on the fly, halting at 100. My first thought was that there was an issue with the entity mapping because I wasn’t able to edit any existing data for this entity. After I successfully solved the mapping issue, I attempted to create 5000 data entries once more. Regrettably, this endeavor failed once more, with an error message referencing time parsing.  The issue was ultimately resolved after I adjusted the date format inside a method that processes a list of objects in batches, that was generating and accumulating SQL INSERT statements to save the object data into a database using batch operations. 

My next attempt was met with yet another setback, this time with an error message indicating a ‘batch too large’ problem. Looking for solutions from other developers who faced similar issues from stack overflow, I discovered that inserting multiple inserts (> 10) into a batch for can have a negative impact on performance. As a result, increasing the batch limit was not an option. After some experimentation, I discovered that only by setting the batch maximum to 15 was I able to generate data that exceeded the 100-entry threshold.

Generating Batch Commit

Continuing from last week’s progress, I needed to add two more seed generators, each representing different entities. This time, the process was more straightforward as I didn’t have to register for additional classes. All I had to do was initialize the required data and create buttons for each entity. Once the setup was done, I eagerly tested the new additions to see if everything was functioning correctly. After a few debugging sessions, I confirmed that both new seed generators were working as intended.

I decided to test the app with 1,000 entities first. The test took an average of 2 minutes to complete, which was reasonable and within an acceptable range. However, a larger workload was actually the goal which is to generate 10,000 for this one entity and 5,000 for another 2 entities.

Feeling ambitious, I decided to raise the stakes and test the app with 5,000 entities this time. To my dismay, the process took significantly longer, stretching beyond 10 minutes. During this time, the entire application froze, and it was evident that the main thread was being used to create all 5,000 data, causing the freezing issue.

Thankfully, Mr. Peter taught me how to create the entities in batches, implementing BackgroundWorker to handle the process more efficiently. This way, the application wouldn’t freeze, and users could continue interacting with it while the data was being generated in the background. By implementing BackgroundWorker, the app was now capable of handling large data generation tasks while keeping the user interface responsive. The experience was smooth, even with 5,000 entities being generated. The background process took some time, but the users could still interact with the app, explore other functionalities, and initiate new data generation tasks without any hindrance.

Furthermore, I enhanced the text box input interface responsible for specifying the desired number of data to be generated. This improvement ensured that non-numeric input was restricted from being displayed on the screen. By following Mr. Peter’s recommendation, I took cues from another entity’s UI to achieve an overall design improvement. In conclusion, the addition of two more seed generators increased the application’s diversity and complexity. Thanks to Mr. Peter’s guidance and the successful integration of BackgroundWorker, the app’s performance and user experience were significantly boosted.

Generating Seed Data

Last week was a wonderful learning experience for me as I dived into the subject of seed data thanks to Mr. Peter’s introduction. Seed data plays a crucial role in providing initial data to an application, which helps developers to interact with the system and understand the user experience before actual user data is available.

Mr. Peter patiently guided me through the process of creating seed data, starting with a practical example. To generate the seed data, we employed a function along with ‘for’ loops. This combination allowed us to efficiently produce a specific amount of data for a particular entity. One fascinating aspect was the utilization of GUIDs (Globally Unique Identifiers) to generate unique data. We organized this seed data generation process within a dedicated view model, specially designed for creating seed data.

With the essential data initialized, I proceeded to create the corresponding view. Keeping it simple yet effective, I added a button for each entity that I intended to populate with seed data. This approach allowed me to generate the desired amount of data for each entity with just a click of a button.

Prior to testing the application, I made sure to register the navigation, ensuring that users could seamlessly navigate through the application once the seed data was in place. However, an unexpected hurdle surfaced when I mistakenly clicked on “clean solution” while trying to build the application. This action inadvertently wiped out some of the previously set up configurations, resulting in a debugging session. Fortunately, the difficulties were fixed and the appropriate settings were restored with thanks to the help of Mr Peter.

Despite the hiccup, I was determined to further explore the benefits of seed data and decided to create seed data for another entity. This provided me with additional hands-on experience, and I gained a deeper understanding of how seed data can streamline the testing and development process, making it an indispensable tool in the application development journey.

Replacing the Old Data Transfer Object (DTO) of an Entity

Last week, I embarked on a task that involved replacing an old Data Transfer Object (DTO) for a particular entity, along with its associated address and contact DTOs. The process of updating the DTO also required me to adjust the mappings inside the services, since the old DTO used manual mapping, which I switched to using AutoMapper.

Additionally, as I proceeded with the replacement of the old DTO, I also diligently worked in debug mode, resolving errors in parallel. This approach allowed me to identify and rectify any issues that arose during the transition to the new DTOs. By addressing errors promptly, I ensured a smoother and more efficient integration of the updated DTOs into the existing codebase.

During the initial stages, I was eager to replace multiple DTOs, believing it would lead to a more refined codebase. However, Mr. Peter’s cautioned me from this approach. He advised me to focus solely on the current entity’s DTO, cautioning against unnecessary complexities that might arise from altering multiple DTOs simultaneously. This guidance had helped me maintain a more targeted and manageable scope for the task.

As I delved deeper into the task, I realized the opportunity to optimize my code further. A comprehensive review of my DTO codes enabled me to identify and remove unnecessary DTOs that I had initially considered adding. Eliminating these extraneous DTOs, which added little value to the overall structure, resulted in a more concise and easier-to-maintain codebase.

Last but not least, the changes in DTOs prompted me to reassess the services in the application. I transitioned the service that was being called directly accessing the database to the ones which utilize API connections.

Code Clean Up : Post-Code Review Session

Reflecting on the productive week that passed, I found myself engrossed in undertaking meticulously cleaning up the codebase following an extensive code review session with Mr. Peter. This session encompassed not only the application but also into the user interface. Mr. Peter thoroughly analyzes each and every line of code, ensuring its readability and maintainability for future utilization.

Throughout the session, Mr. Peter had taught me with valuable insights that enriched my understanding of the principles behind writing clean code. Initially, I had held the belief that it was best practice to encompass the entire usage of an entity within the create, update, and delete commands and queries. I had reasoned that by doing so, future developers would be relieved of the burden of defining or initializing them again. However, under Mr. Peter’s guidance, I realized the importance of minimizing the code to include only what is truly necessary, thereby reducing unnecessary clutter and improving overall code efficiency.

One specific aspect that came to light during the review process was the handling of query lists. It dawned on me that it was sufficient to define only the data that would be displayed on the screen or required to be passed to the user interface. This realization enabled me to streamline the code, eliminating any extraneous information and ensuring that it remains concise and purposeful.

As the week progressed and various code cleaning tasks were successfully accomplished, I approached the final assignment at hand, which is the replacement of old DTOs with newer versions. However, in the midst of this process, I encountered a minor setback. I mistakenly attempted to modify a specific element that Mr. Peter promptly clarified that it should not be altered at this stage. He explained that making such changes would necessitate significant code modifications, better suited for future endeavors.

Despite this slight misstep, I am grateful for the wealth of knowledge gained during the code review session. It truly cultivated a deeper understanding of the importance of code cleanliness, readability, and maintainability.

Add-Migration and Code Reviews

Last week, I had the opportunity to apply my knowledge on EF Core’s Add-Migration command. Add-Migration is a command provided by Entity Framework Core (EF Core) that allows a developer to create a new migration based on the changes made to database context. People use Add-Migration when they need to update their database schema to reflect changes made in their application’s data model. The reason I was told to use Add-migration was because I needed to add a new data field into the data model for an entity.

To my surprise, using Add-Migration turned out to be much easier than I anticipated. I took a cue from the previous commit and used it as a reference, ensuring I was on the right track. I also sought clarification from Mr. Peter to verify my understanding of the steps involved. First things first, I initialized the new data field in all the necessary commands: create, update, delete, and query. It was crucial to ensure that the new field was properly integrated into all aspects of data manipulation. Consequently, I diligently updated the tests for create, update, delete, and query until each test passed successfully. 

Moving on to the user interface (UI), I introduced an interface for the new data field, making sure to bind it correctly. It was important to create a seamless connection between the UI and the underlying application logic. With the interface in place, I proceeded to establish the mapping connection both at the application level and within the user interface, ensuring the new field’s values flowed smoothly between the two.

Additionally, I paid attention to the configuration entity responsible for handling its connection. This configuration entity played a vital role in configuring the entity’s properties, relationships, and constraints using EF Core’s Fluent API. I made sure to incorporate the new data field into this entity’s configuration, ensuring its proper representation within the database schema.

With everything set and ready to go, I opened up the Package Manager Console and eagerly executed the command ‘Add-Migration <the migration name>’ and then applied the migration using the ‘Update-Database’ command. This command executed the migration script, effectively creating a new data field table in the database with all the necessary changes incorporated.

Later that week, I had a helpful code review session with Mr. Peter. He carefully reviewed my code and pointed out some mistakes I had made. He also gave me valuable advice on how to write better code. One important lesson I learned from Mr. Peter is the significance of paying attention to every detail when writing code. He stressed that each line of code matters and should be written with care. It’s crucial to write code that is easy to read, understand, and maintain. It became evident that thoroughness and precision in coding were key factors in ensuring the reliability and efficiency of our applications. In a nutshell, my journey with EF Core’s Add-Migration command and the insightful code review session have been immensely valuable and I’m excited to continue applying these lessons in my future coding endeavors.

Optimizing User Interface

In my previous blog post, I shared the difficulties I encountered while working on the contact management functionality. Specifically, I was facing challenges in enabling the ability to delete and update contacts in the contact list. Initially, my assumption was that the issue lay within the code responsible for updating the data in the database. My thoughts were that I might be missing a few code that is crucial for updating to the database. 

After Mr. Peter reviewed the code, it was discovered that the main reason for the problem was the incorrect usage of a specific function. Specifically, instead of using the “Get contact by Id” function from the entity service, I had been using the “Read contact by Id” function. This incorrect usage of the function was causing the problem I was experiencing. In cases where modifications to the database were required, it was crucial to use the “Get” function. The key difference between the two functions was that the “Read” function utilized the “.AsNoTracking” feature, which instructed the code not to track any changes made. In my specific scenario, where updates and deletions needed to be reflected in the database, employing the “Get” function was imperative.

Next, I proceeded to the next task on my agenda, which focused on optimizing the user interface. The first part of this endeavor involved making subtle but impactful modifications to the contact list interface. I paid close attention to the area where users added new contacts, ensuring that the process was intuitive and streamlined.

The following task is to make the UI non-editable while users are in view mode. This aspect allowed me to implement and gain a better understanding of what data binding can do. I used binding to change the IsReadOnly property of TextBox elements based on their current mode. When in view mode, I set IsReadOnly to true, effectively preventing users from making any inadvertent changes. Conversely, in edit mode, I set IsReadOnly to false, empowering users to modify the necessary information.

During this process, Mr. Peter also enlightened me about another valuable feature related to buttons. Specifically, he shared about how buttons could be dynamically hidden in certain scenarios. This feature proved particularly useful in scenarios where certain buttons were unnecessary or irrelevant, allowing for a cleaner and more focused user experience.

Adding a New Data Field


Last week was quite eventful for me as I took on the task of adding a new data field to an entity in my project. Specifically, I wanted to focus on the address of the entity within the entity’s details. Fortunately, the entity’s address was already present in the user interface (UI), so my main objective was to ensure that the address entered by the user was being handled accurately when interacting with the database and when passing it back to the front-end.

To accomplish this, I started by working on the backend. Using the powerful CQRS pattern, I initialized the entity’s address within the create and update commands, as well as the get by ID query. Additionally, I established the necessary mapping connection within the entity’s profile. This backend setup was crucial in ensuring smooth data flow.

Moving on to the UI, I wanted to make the user experience seamless and error-free. I began by initializing the address within the entity’s DTO wrapper and the corresponding list. Furthermore, I ensured that the mapping connection was properly configured within the entity’s profile. I also took the opportunity to improvise and modify the existing state management and to facilitate the interaction of the address in the entity’s detail view model. This view model is responsible for presenting the entity’s detailed information on the frontend.

Eager to see the results, I ran the application and dove into the debugging phase. Initially, things seemed to be progressing well. However, I soon encountered a bug that left me puzzled about its origin. Thankfully, Mr. Peter suggested that I check the entity’s tests to determine if they were passing. It turned out that a few tests were unsuccessful, which gave me valuable insights and a new starting point to resolve the bug. Mr Peter also emphasized the significance of functional tests, not only that it can help me for bug resolution, but also for long-term benefits in future development efforts.

As the week drew to a close, there was one lingering issue that I had not been able to resolve. Whenever I attempted to remove contacts from the contact list, the database failed to update accordingly. This resulted in the unchanged and unremoved contacts persisting in the database. It was a perplexing problem, but one that I was determined to tackle head-on. This week, my primary focus will be on debugging and resolving this issue, with the goal of resolving it within a day.

In summary, last week was filled with progress and challenges. I successfully integrated a new data field into the entity, ensuring that user-entered addresses were handled correctly. While I faced some unexpected bugs, the process of debugging and testing has provided me with valuable insights for moving forward.

Implementing an API Layer Within the View Model

Over the past two weeks, I have been thoroughly exploring the user interface. During the previous week, I was assigned a task by Mr. Peter to modify the way our system interacts with the database within the MVVM architecture. Instead of establishing a direct connection to the database, he has instructed me to implement an API layer within the view models. This API layer will not only facilitate entity creation but also handle updates and deletions of entities.

To begin, I recognized the need for a new Dto Wrapper that would facilitate the interaction between our application and the API when I was studying the existing code provided by Mr Peter. This wrapper encapsulates the necessary data and functionality required for the saving process. With careful consideration, I designed and implemented the Dto Wrapper to seamlessly integrate with the existing codebase.

Next, I established a new service acting as an interface for API calls. This service handles the communication between our application and the API layer. By abstracting the API interaction into a separate service, a cleaner and more modular code is achieved, improving maintainability and testability. With the groundwork laid, I delved into the entity view model, meticulously analyzing the sections that needed modification to transition it into an API layer. Then, in the view model’s constructor, I initialized the interface services, AutoMapper, and dispatcher, setting the stage for seamless integration with the API layer.

In the case where the user pressed ‘Save’, a dialog is executed. This visually indicates the ongoing progress of the data-saving process, enhancing the user experience. Within this execution, the SaveRoutineAsync method is awaited to ensure the data is saved successfully. Based on the outcome of the saving process, different events are published using the Event Aggregator pattern. If the save operation completes successfully, an event is published with the corresponding parameters, such as the Guid, the mode set to SaveComplete, and an Id was retrieved from the Dto wrapper. 

In addition to the progress mentioned above, I also incorporated the entity’s account details, such as its ID, type, and code. I noticed that this data was also required on the entity’s detailed UI page that I was working on. To address this, I added the account details to the entity profile and ensured that the necessary CRUD operations were implemented at the backend.

Furthermore, I successfully implemented the API functionality, allowing for the correct display and seamless saving and updating of all the data. This accomplishment marked a significant milestone in the integration process for the working entity, as the application was now fully utilizing the power of the API to retrieve and manipulate data effectively.

However, as the week came to a close, I encountered a challenge related to the deletion functionality in the entity’s contact list. It appeared that the deletion process was not functioning as expected. This issue will be my focus for the upcoming week, as I aim to investigate and rectify the problem within the view model. By addressing this issue, I will ensure that the deletion of contacts from the entity’s contact list functions smoothly and seamlessly.