EF Core Performance

Last week , I worked on optimizing the runtime of loading inventory items . The problem is a “Cartesian Explosion” that is related to performing joins . When we perform a join , one’s table repeat the X number of time the matched records of another joined table . There are a few ways to avoid the cartesian explosion especially when loading related entities in a huge database :-

  1. AsSplitQuery() introduced by EF core 5.0 . It only works when using Include(). Instead of joining the tables , split queries generate additional SQL query instead of single queries .
  2. IncludeOptimized() introduced by EF core pro . It works similarly to the first method as it drastically decreases the amount of data transferred to avoid generating excessive data that is needed .
  3. Explicitly loading the data needed in the single query .

In conclusion , unfortunately there isn’t one solid solution for loading all entities that fit every scenario . IncludeOptimized() does not support AsNoTracking() and cannot be mixed with Include() . In hindsight , explicit loading should be the way to fix the cartesian explosion problem as there are limitations to using built in functions .

Refactoring code based on Integration Tests

There is few thing had been done, as shown as below that involve Test-Driven Development (TDD):

As some of my repository integration tests failed, I then refactor/alter my existing implementation of updating database from ReadData to GetData. ReadData in repository class has AsNoTracking(), where entity will not be tracked. When we make changes on the entity and will not be updated anyhow after calling context.SaveChanges(). By changing to GetData which allow entity to be tracked and any changes will be updated upon context.SaveChanges(). It also make sure latest data been retrieve after they are changed.

There is many repository test been done such as should add new, should update, should remove, should throw error, should roll back. I make sure these context integration tests passes and proceed to ViewModel classes tests. Following tests is mainly to make sure my implementation works fine under multiple scenario.

Most existing ViewModel integration tests failed as refactor of initialization is needed. ViewModel tests passed after few initialization, however there is few test involving DialogServiceMock failed to launch action of dialog in ViewModel class upon debugging. Despite that, the particular scenario works well when I run the application. Therefore, I need to figure out the factor behind failure of my test.

Utilizing EF Core Exception Handling & Debugging CRUD methods

I continued my progress with fixing delete function, which suppose to remove linked data in multiple table across the database. The failure of delete function due to certain entity are set as foreign key of other table. This problem is solved by setting null value for related foreign key in delete function. As the value of foreign key is null, deletion is allowed as how it suppose to behave.

Next, I alter sequence of textbox in View class. To ensure best user experience when they uses hotkey “Tab” to navigates over to next textbox available.

Then, Remove validation made in ViewModel class and implement it in repository class. Allowing EF core throw error whenever unique entity is input multiple time. The error will be catch, hence, prompt dialog box to notify user of application. This way is a better implementation reduce number of code, however it cause few issue in application. Issue such as user unable to create new user after error popped up to indicate similar user id appears in database.

In conjunction, RepositoryActualDbTests class is created to mock my situation. I arrange declaration, execute three seperate input ( 1st input : id = 1, 2nd input : id = 1, 3rd input : id = 2 ) , and assert expected behaviour ( Total of 2 input should be saved input database ). After quite an amount of testing and struggling, the bug is then fixed, however it requires chain fix in code. Therefore, my supervisor advice me to try out a different implementation for my create function by mocking a test.

Button Behaviour, Concurrency Situation and Sourcetree

To begin with the week, I continued from last part I left off previous week. I did some research and some trials to allow the application to store data into two attributes from one input. It is troublesome for me at first, but I managed it after half day of experimenting and with the guidance of supervisor.

After I figured out storing data, I then started to plan on how I should proceed my task as below:
1. Read and compare two value from columns of database.
2. Statement for decision making algorithm.
3. Call existing functions to control behaviour of delete button.
4. Delete selected row when button is Enabled.
5. Pop ups dialog box for confirmation as delete button clicked.
6. Pop ups Error message whenever selected row is unable to be deleted.

Next, I begin with some testing based on existing code, hence, start my implementation. First of all, I learnt that AsNoTracking( ) in Entity Framework is useful when reading data from database. It is said so, AsNoTracking queries are quicker to execute compared to tracking queries. I understood that, I should use it whenever I don’t need to update retrieved data. However, I retrieved the data using tracking query, and perform test using logger to make sure I implementing it correctly. I proceed with comparing and if-else logic to decide behaviour of button.

After that, I implement a dialog box confirmation upon user’s delete command. Also, when logic allows deletion of selected data, it will completely remove it from database table. When logic forbid deletion of data, error message is invoked to inform user stating “Unable to delete data as it has been used”.

Apart from given task, I also learnt about idea of concurrency when things happen at the same time in a system. There is situation whenever two or more user adding new data with the same ID at the same time. Hence, there are some few example codes, for me to go through in order to handle such situation.

Lastly, I get in touch on using Sourcetree, A GUI software that is simplified to interact with git repositories. I learnt to use Sourcetree to stash and apply my version of codes of my project file. Besides, I also learnt how to solve conflicts when a group project is combined in Sourcetree. I could not agree less that Sourcetree provides idea of git and good features that support team implementation.