Группировка Linq to SQL со встроенными списками вызывает слишком много запросов

#c# #sql #linq

#c# #sql #linq

Вопрос:

Я разрабатываю запрос для захвата и объединения некоторых таблиц SQL в C #, и у меня возникли некоторые проблемы с группировкой и перечислением в наборе данных. Мой запрос приведен ниже. Это дает мне данные в формате, который я ищу, но это занимает слишком много времени, когда я пытаюсь добавить перечисляемый список, как указано ниже. Когда я заглядываю под капот, я вижу, что он выполняет слишком много SQL-запросов. Я бы хотел, чтобы это было только одно. Использование LINQPad:

 void Main()
{
    var nightlyRuns = (from a in LoadTestSummaries
                join b in LoadTestTestSummaryData
                on a.LoadTestRunId equals b.LoadTestRunId
                where a.TargetStack == "LoadEnv" amp;amp;
                a.TestGuid != null amp;amp;
                a.StartTime != null amp;amp;
                a.LoadTestRunId != null

                orderby a.StartTime
                group new {a, b} by new
                {
                    a.TestGuid,
                    a.Name,
                    a.Description,
                    a.StartTime,
                    a.Duration,
                    a.NumAgents,
                    a.NumHosts,
                    a.PassFail,
                    a.ResultsFilePath,
                    a.Splunk
                } 
                into g
                let scenarioStart = g.Min(s => s.a.StartTime) ?? g.Min(s => s.a.DateCreated)        
                let testCases = g.Select(s => s.b)
                orderby scenarioStart 
                select new 
                {
                    TestGuid = g.Key.TestGuid,
                    ScenarioRun = new 
                    {
                        Name = g.Key.Name,
                        Description = g.Key.Description,
                        StartTime = scenarioStart,
                        Duration = g.Key.Duration,
                        NumAgents = g.Key.NumAgents,
                        NumHosts = g.Key.NumHosts,
                        Result = g.Key.PassFail,
                        ResultsFilePath = g.Key.ResultsFilePath,
                        SplunkLink = g.Key.Splunk,
                        // PROBLEM: Causes too many queries:
                        TestRuns = from t in testCases select t.TestCaseId
                    }
                }).ToLookup(g => g.TestGuid, g => g.ScenarioRun);

    nightlyRuns["ba593f66-695f-4fd1-99c3-71253a2e4981"].Dump();
}
  

Строка «TestRuns» вызывает избыточные запросы. Есть идеи, что я здесь делаю не так?

Спасибо за любую информацию.

Комментарии:

1. Правильно ли настроены внешние ключи в вашей базе данных и объектах? Обычно соединение здесь не требуется при использовании Linq to entities, если ссылки указаны правильно.

2. К сожалению, нет — я полагаю, я мог бы добавить FK, но у меня нет кода, который записывает данные в таблицы, поэтому мне также нужно добавить триггер для заполнения этого. Я попробую это, если не смогу прийти к решению. На данный момент я хотел бы понять, что я делаю неправильно.

3. Это большой вопрос, Брайан, я хотел бы оставить свой ответ в качестве комментария, но если вы посмотрите, что у меня есть, и ссылку, это должно помочь, если я что-то не пропустил.

Ответ №1:

Сложный ответ для тестирования, но я думаю, что мы можем избежать группировки и нескольких запросов с помощью чего-то вроде этого: (https://msdn.microsoft.com/en-us/library/bb311040.aspx )

            var nightlyRuns = (from a in LoadTestSummaries
            join b in LoadTestTestSummaryData
            on a.LoadTestRunId equals b.LoadTestRunId
            where a.TargetStack == "LoadEnv" amp;amp;
            a.TestGuid != null amp;amp;
            a.StartTime != null amp;amp;
            a.LoadTestRunId != null
            into testGroup

            select new 
            {
                TestGuid = a.TestGuid,
                ScenarioRun = new 
                {
                    Name = a.TestGuid,
                    Description = a.Description,
                    StartTime = a.StartTime ?? a.DateCreated,
                    Duration = a.Duration,
                    NumAgents = g.Key.NumAgents,
                    NumHosts = a.NumHosts,
                    Result = a.PassFail,
                    ResultsFilePath = a.ResultsFilePath,
                    SplunkLink = a.Splunk,
                    // PROBLEM: Causes too many queries:
                    TestRuns =testGroup
                }
            }).OrderBy(x=>x.StartTime).ToLookup(x => x.TestGuid, x => x.ScenarioRun);

            nightlyRuns["ba593f66-695f-4fd1-99c3-71253a2e4981"].Dump();
  

Комментарии:

1. Я не совсем понимаю «в тестовую группу» здесь? Вы собирались группировать?

2. О, неважно, «в тестовую группу» должно быть после «вкл» и перед «где». Это определенно сводит его к одному запросу, очень полезно, спасибо. Что-то не так с «startTime», но я должен быть в состоянии понять это. Отправит ответ…

3. Предположим, я хочу добавить что-то из таблицы b в select для анонимного типа ScenarioRun. Например:

4. Слишком рано нажал enter. Например, если я хочу, чтобы Duration = b.Длительность указана выше, как я могу включить таблицу b в группировку? Я вижу «Имя ‘d’ не существует в текущем контексте».

5. А, неважно, думаю, я понял это. Перепутал мои таблицы!