Хранение внешнего ключа для основного первичного ключа в каждой таблице - PullRequest
0 голосов
/ 25 мая 2020

Допустим, у нас есть таблица Users с ID в качестве первичного ключа, и у пользователя есть следующие связанные сущности:

UserSubjects(SubjectId <PK>,UserId <FK>)
SubjectPapers(PaperId<PK>,SubjectId<FK>)

Теперь, согласно приведенным выше таблицам, по соображениям безопасности userId необходимо передать в качестве параметра, чтобы получить все SubjectPapers для Subject, которые связаны с пользователем, вместо того, чтобы просто передавать SubjectId.

возьмем этот метод, например:

 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();
 }

В описанном выше методе пользователь должен быть включен в запрос, чтобы подтвердить, что он делает запрос на получение одного из своих субъектов.

Что, если также SubjectPapers имеет больше связанные сущности теоретически. Улучшит ли сохранение внешнего ключа UserId производительность запроса за счет добавления некластеризованного индекса в оба столбца (UserId и SubjectId)? Есть ли побочные эффекты? или есть ли другой способ избежать включения родительского пользователя в каждую связанную сущность? Любые предложения приветствуются.

1 Ответ

1 голос
/ 25 мая 2020

Если для поиска темы требуется UserId, тогда Subject является « Weak Entity », а UserID должен быть ведущим столбцом в его составном первичном ключе.

UserSubjects(UserId <PK,FK>,SubjectId <PK>)

IE как

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; }
}

и настроен следующим образом:

modelBuilder.Entity<Subject>().HasKey(s => new { s.UserID, s.SubjectId });
modelBuilder.Entity<Subject>().Property(s => s.SubjectId).ValueGeneratedOnAdd();

Это оптимизирует поиск по UserID и предотвращает необходимость в таблице Subject нескольких индексов. Он имеет один кластеризованный индекс для (UserID, SubjectID) вместо двух отдельных индексов для двух столбцов.

...