2009-09-22 2 views
1

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

Для моих сообщений db я создал веб-службу, которая использует Linq2SQL. Чтобы преодолеть проблему срыва моего веб-сервиса, я собираю данные, из-за которых иногда возникают 3 вызова веб-сервисов, чтобы получить все это.

О проблеме. При получении больших объемов данных процесс перечисления «ToList()» занимает несколько секунд, что составляет дольше желаемого времени загрузки. Типичная продолжительность моего запроса - около 1500 в соответствии с SQL Profiler. Вызов ToList() может занять до 4 секунд для 1000 записей, что кажется экстремальным.

Мой главный вопрос: есть ли что-нибудь, что можно сделать, чтобы ускорить этот процесс? Или, может быть, есть лучший способ получить большие объемы данных из db в приложение silverlight?

Дополнительная информация:

Моя ссылка LINQ закодирована в частичном классе моего контекста данных. Это связано с неудобной хранимой процедурой, тип возврата которой не будет хорошо работать с файлом dbml.

Я также создал основной объект, который я поставил в качестве возвращаемого типа для моего объекта, состоящий в основном из быстрых определений свойств, такие как:

public Guid Id {get; set;}

Следования до Спрашивается, при определении LinQ хранимой процедуры вызова и возвращаемые типы, есть ли какие-либо атрибуты, которые помогают ускорить процесс или я просто привяжу его к очень базовому объекту?

+2

Когда вы говорите: «перечисление может занять до 4 секунд», что именно вы имеете в виду? Здесь у вас много областей, которые могут быть узкими местами. Ради здравомыслия, я предлагаю вам разделить их полностью, чтобы мы знали, что происходит. –

+0

Извините, если я был немного многословным. То, что я имею в виду, сразу после вызова моей хранимой процедуры, мой вызов ToList() может занять несколько секунд, что кажется немного. –

+0

Бадди, сколько объектов создается за это время? Когда вы вызываете ToList(), вы создаете десятки объектов или тысячи? –

ответ

0

Сначала вам нужно выяснить, где находится узкое место; обычные преступники:

  • латентность; вы указываете звонки (а не 300), поэтому я не думаю, что это проблема
  • bandwidth; как жир - объекты, которые вы хотите отправить
  • производительность основного db-запроса; быстро получается SELECT
  • ленивые проблемы с поломкой; вы фактически выполняете операции n + 1 db?

Изучите последние два с помощью трассировки SQL или некоторого простого ведения журнала (LINQ-to-SQL имеет свойство DataContext.Log, которое может быть очень полезно здесь); трассировка SQL может быть более точной.

Чтобы выяснить, является ли количество поездок от клиента Silverlight на веб-сервер, попробуйте сетевую трассировку; Fiddler или WireShark должны выполнять эту работу.

Если пропускная способность является проблемой (т.Ввиду большого объема данных по проводам), а затем рассмотреть:

  • сжатия
  • другой сериализатору

Например, Protobuf-сеть может сделать огромные различия по размеру на проводе; может потребоваться несколько иной код, хотя самый простой способ - передать byte[] по этой услуге (и, если возможно, использовать MTOM).

+0

Я переместил db локально, что помещало вещи в перспективу. До того, как db прошел через облако и потребовалось около 4 секунд, чтобы вернуться ко мне. Я также перечислял все 3000+ строк, когда я принимал только 1000. В конечном счете, я нахожусь чуть больше секунды за звонок на свой db, а чуть более 2 секунд для звонка туда и обратно в мою сеть оказание услуг. Не так уж плохо, но высшие силы хотят больше скорости. Единственное, что я могу придумать, - это найти способ получить все данные сразу. Это приводит к новому вопросу по адресу http://stackoverflow.com/questions/1462452/silverlight-data-access –

0

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

0

Ответ заключается в прекращении использования ToList() в целом. Не загружайте все свои данные в свой веб-сервис, а затем возвращайте его клиенту как один огромный кадр. Возьмите потокный подход; так что вместо (псевдокода)

for each record in query; 
    add record to list 

for each record in list; 
    create a line of response 
    write line to response. 

Не можете ли вы передать ответ так?

for each record in query; 
    create a line of response 
    write line to response. 

в цикле, в вашем веб-службы должны пройти по результату запроса одной записи в то время, и использование памяти будет абсолютно минимальным.

0

Чтобы избежать использования ToList(), попросите прокси-сервер веб-службы генерировать код, который использует коллекцию List. Сделайте это, найдя ссылку на службу в своем проекте Visual Studio. Щелкните правой кнопкой мыши> Настроить ссылку на службу. Затем под типом коллекции выберите коллекцию, поддерживающую методы linq. Я бы использовал System.Collection.Generic.List. Затем обновите ссылку на службу, чтобы восстановить файл References.cs.

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