patterncsharpMinor
Joining tables with EF
Viewed 0 times
withtablesjoining
Problem
Here is my database:
Here is my
Which way of joining table is better and faster?
-
Using something like this in a razor page:
Here is my
viewModel:public class groupsFoldersViewModel
{
private DAL.educationSocialNetworkEntities DB = new DAL.educationSocialNetworkEntities();
public List sharedFolders { get; set; }
public groupsFoldersViewModel(int gid , int uid)
{
DAL.group_table group = DB.group_table.Find(gid);
if (group != null)
{
sharedFolders = group.sharedFolders_table.ToList();
}
}
}Which way of joining table is better and faster?
- One heavy query for joining tables in
ViewModelconstructor
-
Using something like this in a razor page:
@foreach (var f in Model.sharedFolders)
{
@f.folder_table.folderName
}Solution
At the end of the day, only you can tell what performs best. But there are two things that in most cases will help improve performance.
Essentially, you do
And in the view, for each
That's one query for each
So you end up having 1 + 1 + n queries.
No doubt, it's better to turn these into one. For example:
But since you only seem to use
(Note that this changes your model data type.)
These queries return complete entities. But in the end, you only display one field (let's ignore the fact that in reality you probably do more). So you may as well get that field only.
Reducing the number of fields in a query can considerably improve performance, especially when records are wide and many joins are involved. I often see people focus on reducing the number of records, but reducing the number of fields is equally important.
In your reduced example, it's enough to get only the names from the database:
(again, this changes the model type)
Now you have one lean and mean query, instead of 1 + 1 + n wide queries.
- Reduce the number of queries.
Essentially, you do
DAL.group_table group = DB.group_table.Find(gid);
sharedFolders = group.sharedFolders_table.ToList();And in the view, for each
sharedFolders_table you diplaysharedFolders_table.folder_table.folderNameThat's one query for each
sharedFolders_table.So you end up having 1 + 1 + n queries.
No doubt, it's better to turn these into one. For example:
sharedFolders = DB.sharedFolders_table
.Include(s => s.sharedFolders_table)
.Where(s => s.groupId == gid).ToList();But since you only seem to use
folder_table.folderName it should be better yet to get only folder_table objects:sharedFolders = DB.sharedFolders_table
.Where(s => s.groupId == gid)
.Select(s => s.folder_table)
.ToList();(Note that this changes your model data type.)
- Use a projection
These queries return complete entities. But in the end, you only display one field (let's ignore the fact that in reality you probably do more). So you may as well get that field only.
Reducing the number of fields in a query can considerably improve performance, especially when records are wide and many joins are involved. I often see people focus on reducing the number of records, but reducing the number of fields is equally important.
In your reduced example, it's enough to get only the names from the database:
sharedFolders = DB.sharedFolders_table
.Where(s => s.groupId == gid)
.Select(s => s.folder_table.folderName)
.ToList();(again, this changes the model type)
Now you have one lean and mean query, instead of 1 + 1 + n wide queries.
Code Snippets
DAL.group_table group = DB.group_table.Find(gid);
sharedFolders = group.sharedFolders_table.ToList();sharedFolders_table.folder_table.folderNamesharedFolders = DB.sharedFolders_table
.Include(s => s.sharedFolders_table)
.Where(s => s.groupId == gid).ToList();sharedFolders = DB.sharedFolders_table
.Where(s => s.groupId == gid)
.Select(s => s.folder_table)
.ToList();sharedFolders = DB.sharedFolders_table
.Where(s => s.groupId == gid)
.Select(s => s.folder_table.folderName)
.ToList();Context
StackExchange Code Review Q#114465, answer score: 2
Revisions (0)
No revisions yet.