Execute a Stored Procedure that gets Data from Multiple Tables in EF Core

Saurabh Pati
HackerNoon.com
6 min readApr 28, 2019

--

In EF Core there is not quite yet an elegant way to fetch data from multiple tables by a stored procedure. Lets build one.

Why am I writing this.

The above issue is the reason why I feel this article is necessary. At the time of writing this article, EF Core’s prescribed way of executing a stored procedure is context.Blogs.FromSql("EXEC Sp_YourSp") but that is only possible if your stored procedure returns data from a particular DB Set (one table or one entity).

Lets look at how we can work it around until the above issue is resolved if a stored procedure gets data from multiple tables.

The setup

We are going to recreate a scenario where we need to do just the above. We are going to write a small ‘Todo’ API.

Here is the gist link containing all the files shown below

Entities/Models

User.cs

Team.cs

UserTeam.cs

TaskItem.cs

Status.cs

Entity.cs

Now lets say we need to see a progress report where we need the information of teams and users along with the count of all tasks and the tasks which are in todo, in progress and done state. A stored procedure that accepts optional teamId and userId to get the progress report of all/one team(s) fits the solution to our requirement.

The stored procedure

Lets create a stored procedure as discussed above.

Sp_ProgressReport.sql

The solution

Lets create an entity which is the response of this stored procedure. You can omit creating an entity if you want to as you can directly map the response to an object or dynamic but it helps to have an entity when

  • You have to modify or process the response to apply business logic.
  • There are several related responses of such kind and you want to use some object oriented principles to reuse your entity.

ProgressReportEntity.cs

We are going to create a repository for executing the stored procedure. I am not too great a fan of repositories but a lot of developers find it helpful, so I am going to stick to the repository pattern for now. You can create whatever data access abstraction you like.

Lets create a few extension methods that will help us irrespective of any pattern we follow.

SprocRepositoryExtensions.cs

With this, the repository implementation becomes quite simple.

SprocRepository.cs

Once we have got DbCommand from GetStoredProcedure we can call the ExecuteStoredProcedure or ExecuteStoredProcedureAsync from the extension method. I am going to take the liberty to inject repository directly into the controller for now. You can have a business layer abstraction if you want to modify the response if for e.g. you want to calculate the percentage of open, in progress and done tasks.

ReportsController.cs

The result

Now once we execute this controller by passing 0 in teamId and userId, it will fetch us the progress report of all teams and all users.

Here is the result:

The Conclusion

I hope this really helps you if your requirement or interest aligns with this article. I have made a repository for the same where you can refer this app.

Checkout Jeremy Sinclair’s repository for a full blown abstraction of the same

and lastly, do keep a tab on the open issue #245 in ef core’s github repo for a better solution.

--

--