Многопоточные подзапросы с использованием Entity Framework выдают ошибки - PullRequest
4 голосов
/ 19 мая 2011

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

Использование приведенного ниже упрощенного кода приведет к неосторожному генерированию сообщения «Основной поставщик не удалось открыть».

using (var context = getNewContextObject())
{
    var result = new SomeResultObject();
    var parentQuery = context.SomeTable.Where(x => x.Name = "asdf");

    Parallel.Invoke(() =>
        {
            result.count1 = parentQuery.Where(x => x.Amount >= 100 & x.Amount < 2000).Count();
        }, () =>
        {
            result.count2 = parentQuery.Where(x => x.Amount < 100).Count();
        }
        , () =>
        {
            result.count3 = parentQuery.Where(x => x.Amount >= 2000).Count();
        }
    );

}

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

    Parallel.Invoke(() =>
        {
            var subQuery = parentQuery.Where(x => x.Amount >= 100 & x.Amount < 2000).Count();
            subQuery.Context = getNewContextObject();
            result.count1 = subQuery.Count();

        }, () =>
        {
            var subQuery = parentQuery.Where(x => x.Amount < 100).Count();
            subQuery.Context = getNewContextObject();
            result.count2 = subQuery.Count();
        }
        , () =>
        {
            var subQuery = parentQuery.Where(x => x.Amount >= 2000).Count();
            subQuery.Context = getNewContextObject();
            result.count3 = subQuery.Count();
        }
    );

}

1 Ответ

7 голосов
/ 20 мая 2011

Я не уверен, как это в точности относится к вашей проблеме, но ни одна из функций EF не является поточно-ориентированной, поэтому я ожидаю, что выполнение нескольких запросов в одном и том же экземпляре контекста параллельно может привести к разрыву по любой причине. Например, они обращаются к одному и тому же свойству соединения в контексте, но потоки не знают друг о друге, поэтому они могут закрыть соединение с другим потоком или заменить экземпляр другим экземпляром соединения (вы можете попробовать открыть соединение вручную, прежде чем запустить параллельное соединение. и закройте его, как только все потоки будут завершены, но это не должно быть единственной проблемой).

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...