2

У меня есть следующие классы, которые поддерживаются EF6 и базой данных SQL Server 2012. У меня есть около 500 записей в таблице вопросов, 250 в таблице проблемы, и 20 в подтемы таблице:У меня есть запрос EF, который очень медленный. Как я могу отладить это?

public class Question 
{ 
    public int QuestionId { get; set; } 
    public int ProblemId { get; set; } 
    public int QuestionStatusId { get; set; } 
    public string Text { get; set; } 
    public string AssignedTo { get; set; } 
    public DateTime AssignedDate { get; set; } 
    public int QuestionTypeId { get; set; } 
    public virtual Problem Problem { get; set; } 
    public virtual QuestionStatus QuestionStatus { get; set; } 
    public virtual QuestionType QuestionType { get; set; } 
} 
public class Problem 
{ 
    public Problem() 
    { 
     this.Questions = new List<Question>(); 
    } 
    public int ProblemId { get; set; } 
    public int SubTopicId { get; set; } 
    public string Text { get; set; } 
    public virtual SubTopic SubTopic { get; set; } 
    public virtual ICollection<Question> Questions { get; set; } 
} 
public partial class SubTopic 
{ 
    public SubTopic() 
    {; 
     this.Problems = new List<Problem>(); 
    } 
    public int SubTopicId { get; set; } 
    public int Number { get; set; } 
    public int TopicId { get; set; } 
    public string Name { get; set; } 
    public virtual ICollection<Problem> Problems { get; set; } 
    public virtual Topic Topic { get; set; } 
} 

настроить следующие карты:

public ProblemMap() 
    { 
     // Primary Key 
     this.HasKey(t => t.ProblemId); 
     this.HasRequired(t => t.SubTopic) 
      .WithMany(t => t.Problems) 
      .HasForeignKey(d => d.SubTopicId) 
      .WillCascadeOnDelete(false); 
    } 
    public QuestionMap() 
    { 
     // Primary Key 
     this.HasKey(t => t.QuestionId); 
     // Relationships 
     this.HasRequired(t => t.Problem) 
      .WithMany(t => t.Questions) 
      .HasForeignKey(d => d.ProblemId); 
     this.HasRequired(t => t.QuestionStatus) 
      .WithMany(t => t.Questions) 
      .HasForeignKey(d => d.QuestionStatusId); 
     this.HasRequired(t => t.QuestionType) 
      .WithMany(t => t.Questions) 
      .HasForeignKey(d => d.QuestionTypeId); 
    } 
    public SubTopicMap() 
    { 
     // Primary Key 
     this.HasKey(t => t.SubTopicId); 
     // Relationships 
     this.HasRequired(t => t.Topic) 
      .WithMany(t => t.SubTopics) 
      .HasForeignKey(d => d.TopicId); 
    } 

Я пытаюсь сделать запрос на них выглядит следующим образом:

IList<Question> questions; 
questions = _questionsRepository 
    .GetAll() 
    .Where(q => q.Problem.SubTopic.TopicId == topicId || topicId == 0) 
    .Where(q => q.QuestionStatusId == questionStatusId || questionStatusId == 0) 
    .Where(q => q.AssignedTo == assignedTo || assignedTo == "0") 
    .Where(q => q.ModifiedBy == modifiedBy || modifiedBy == "0") 
    .Include(q => q.Problem) 
    .Include(q => q.Answers) 
    .ToList(); 

Проблема в том, что запрос начинается, но никогда не возвращается. Есть ли что-то, что я делаю неправильно? Есть ли способ узнать, какой запрос он пытается выполнить с базой данных?

Может быть, следующее, что делает вещи работать медленно:

q.Problem.SubTopic.TopicId == topicId 

Вот хранилище GETALL()

public virtual IQueryable<T> GetAll() 
    { 
     return DbSet; 
    } 
+1

Считаете ли вы использование таких инструментов, как [Entity Profiler] (http://www.hibernatingrhinos.com/products/EFProf)? Я попробовал это с одним из моих запросов и очень полезен. Я уверен, что есть и другие инструменты. – Marcel

+0

Можете ли вы показать нам код вашего репозитория (+ 'GetAll()')? Вы должны указать 'Include()' перед 'Where()'. Кроме того, проверьте свой сгенерированный SQL-запрос во время отладки, проверьте его и проверьте его непосредственно в SQL Server. – glautrou

+0

@glautrou. Я включил GetAll() в вопросы. Я не знал, что должен делать Include() до Where() У меня есть несколько идей о проверке вещей. Надеюсь, что-то может мне помочь.Спасибо –

ответ

2

Вы можете использовать Linq to Entity query visualizer

Это бесплатное расширение для Visual Studio. Описание:

Просмотреть исходный SQL (MS SQL, DB2, Oracle и т. Д.) LInQ для объектов ObjectQuery при отладке в Visual Studio 2008/2010 /. Смотрите также лямбда-выражения, параметры редактирования запроса, данные вид DB Connection, просматривать результаты запроса, а также экспортировать результаты в MS Excel (нет MS Excel требуется)

Вы можете скопировать запрос и вставить его в SQL Server, если вам нужно.

Вы также можете использовать LinqPad. Это приложение позволяет вам писать тестовые выражения LINQ, предназначенные для разных бэкэндов баз данных и различных вариантов LINQ: LINQ to SQL, LINQ to Entities, LINQ to Objects ...

И, наконец, free version of DevArt LINQ Insight (express versions). Это также расширение VS.

+0

Спасибо. Я попробую это. Может быть, именно то, что я ищу. –

+0

Добавлены 2 дополнительных ссылки на различные инструменты LINQ. Я не тестировал первый с EF6, но с EF5. – JotaBe

+1

ВНИМАНИЕ: ознакомьтесь с отзывами для второй ссылки. По-видимому, это пробная версия за 30 дней и после этого выдает некоторые функции. Не «совершенно» бесплатно. – statue

0

Я не думаю, что этот запрос работает вообще. У вас нет объединений между вопросом и проблемой, а также проблемой и подтемами. Если вы переписываете запрос с помощью объединений, я не вижу причин для его неправильной работы.

попробовать что-то вроде этого:

from q in db.Questions 
join p in db.Problems on q.ProblemId equals p.ProblemId 
join s in db.SubTopics on s.SubTopicId equals p.SubTopicId 
where q.QuestionStatusId == questionStatusId && 
q.AssignedTo == assignedTo 
q.ModifiedBy == modifiedBy 
s.TopicId == topicId 
select q 

Для отладки я использую SQL Profiler. После запроса из SQL Profiler вы можете использовать советник по настройке ядра базы данных, чтобы узнать, отсутствуют ли в базе данных индексы.

Смежные вопросы