I am using CoolStorage as an ORM and have a question regarding how often the database is being queried.
I am returning a list of teams, and also want to display the number of users contained within each team. I am returning the teams by calling Team.List()
and there are 2 options I can think of how to return the number of users. One is by adding a property to the Team class which returns a count of its [OneToMany] SysUsers, and the other is to use LINQ on the result returned by Team.List()
. The code below demonstrates both methods, both of which return the same result.
I am trying to understand how this affects database interaction, for example will it first return a list of Teams, and then run a separate query against each one to get the number of users? If I then wanted to add another 2 or 3 fields would it then run another separate query for each additional field? Is there any difference between the two approaches?
My concern is that if the connection isn't great this could make even simple queries unresponsive.
The option exists in CoolStorage to run ad hoc SQL queries instead, am I better off doing this instead for more complex queries? Or am I worrying over nothing?
CSList<Team> teams = Team.List();
// Counting number of objects
var d = from t in teams
select new
{
TeamID = t.TeamID,
TeamName = t.TeamName,
NoUsers = t.SysuserTeams.Count
};
// Using property added to Team class
var e = from t in teams
select new
{
TeamID = t.TeamID,
TeamName = t.TeamName,
NoUsers = t.NumberOfUsers
};
DataGridView dgv = this.dgvTeams;
dgv.DataSource = d.ToList();
// Same result as
dgv.DataSource = e.ToList();
Having seen from the SQL log being generated that it was running a new query for each row in the Teams result, I got in touch with the CoolStorage developers who kindly responded a neat solution.
There are two options, either the OneToMany
property for Sysusers
can be tagged as [Prefetch]
or this can be explicitly specified for each query such as Team.List().WithPrefecth("Users")
. Either way, it now only runs one additional query for the user records, rather than a query per row