Reputation: 3649
Say we have the table Users
with an ID
as a primary key, and the user has the following related entities:
UserSubjects(SubjectId <PK>,UserId <FK>)
SubjectPapers(PaperId<PK>,SubjectId<FK>)
Now as per the above tables, for security reasons the userId
must be passed as a parameter to get all the SubjectPapers
for a Subject
that are related to the user instead of just passing the SubjectId
.
take that method for example:
public List<SubjectPaper> GetBySubject(int userId, int subjectId)
{
return _context.SubjectPapers
.Include(k => k.UserSubject)
.Where(k => k.SubjectId == subjectId && k.UserSubject.UserId == userId)
.ToList();
}
In the above method, the user has to be included in the query to validate that he is making the request to get one of his subjects.
What if also SubjectPapers
has more related entities theoretically. Will storing a UserId
Foreign key improve the query's performance by adding a non-clustered index on both columns (UserId and SubjectId)? Is there any side effects? or is there any other way to avoid including the parent user each related entity? Any suggestion is appreciated.
Upvotes: 0
Views: 68
Reputation: 89246
If UserId is requried to find a Subject, then Subject is a "Weak Entity" and the UserID should be the leading column in it's compound primary key.
UserSubjects(UserId <PK,FK>,SubjectId <PK>)
IE like
public class User
{
public int UserId { get; set; }
public virtual ICollection<Subject> Subjects { set; } = new HashSet<Subject>();
}
public class Subject
{
public int UserID { get; set; }
public int SubjectId { get; set; }
public virtual User UserId { get; set; }
}
and configured like this:
modelBuilder.Entity<Subject>().HasKey(s => new { s.UserID, s.SubjectId });
modelBuilder.Entity<Subject>().Property(s => s.SubjectId).ValueGeneratedOnAdd();
This optimizes for retrieval by UserID and prevents the Subject table from requiring multiple indexes. It has a single clustered index on (UserID,SubjectID) instead of needing two separate indexes on the two columns.
Upvotes: 1