Загрузка> 10000 строк из таблицы базы данных в asp.net - PullRequest
2 голосов
/ 01 сентября 2009

Как мне обеспечить предоставление функции загрузки на странице asp.net для загрузки ряда строк из таблицы базы данных, представленной в виде класса linq2sql, который имеет только примитивные типы для членов (в идеале в формате, который легко читается Excel)

* 1003 Е.Г. *

public class Customer
{
public int CustomerID;
public string FirstName;
public string LastName;
}

То, что я пробовал до сих пор.

Первоначально я создал DataTable, добавил все данные о клиентах в эту таблицу и связал их с DataGrid, затем имел кнопку загрузки с именем DataGrid1.RenderControl в HtmlTextWriter, который затем был записан в ответ (с типом содержимого «application»). /vnd.ms-excel "), и это работало нормально для небольшого числа клиентов.

Однако , теперь число строк в этой таблице> 10 000 и ожидается, что оно достигнет 100 000, поэтому становится все более невозможным отображать все эти данные на странице, прежде чем пользователь сможет щелкнуть кнопка загрузки.

Итак, вопрос в том, как я могу предоставить возможность загружать все эти данные без необходимости сначала отображать их в DataGrid?

Ответы [ 8 ]

3 голосов
/ 01 сентября 2009

После того как пользователь запросит загрузку, вы можете записать данные в файл (.CSV, Excel, XML и т. Д.) На сервере, а затем отправить перенаправление на URL файла.

1 голос
/ 01 сентября 2009

Всего лишь предупреждение, в Excel есть ограничение на количество строк данных - ~ 65к. CSV будет в порядке, но если ваши клиенты импортируют файл в Excel, они столкнутся с этим ограничением.

1 голос
/ 01 сентября 2009

Вы обязательно должны проверить библиотеку FileHelpers . Это бесплатный, отличный набор утилит для работы с такой ситуацией - импорт и экспорт данных из текстовых файлов; либо с разделителями (например, CSV), либо с фиксированной шириной.

Он предлагает множество вариантов и способов ведения дел, и БЕСПЛАТНО , и он действительно хорошо работает в различных проектах, в которых я его использую. список объектов - что бы у вас ни было.

У него даже есть импорт / экспорт для файлов Excel, так что вы действительно получаете кучу вариантов.

Просто начните использовать FileHelpers - это сэкономит вам столько скучного набора текста и прочего, что вы не поверите: -)

Марк

1 голос
/ 01 сентября 2009

Помимо разумного предложения сначала сохранить данные на сервере в файл в одном из ответов, я хотел бы также отметить, что нет причин использовать DataGrid (это также один из ваших вопросов). DataGrid является излишним практически для всего. Вы можете просто перебирать записи и сохранять их напрямую с помощью HtmlTextWriter, TextWriter (или просто Response.Write или аналогичных) в файл сервера или в поток вывода клиента. Это кажется мне очевидным ответом, поэтому я должен что-то упустить.

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

1 голос
/ 01 сентября 2009

Я использовал следующий метод в блоге Мэтта Берсета для больших наборов записей.

Экспорт GridView в Excel

Если у вас есть проблемы с тайм-аутом запроса, попробуйте увеличить время http-запроса в web.config

0 голосов
/ 01 сентября 2009

Итак, после небольшого исследования первое решение, которое я в итоге попробовал, состояло в том, чтобы использовать слегка измененную версию образца кода из http://www.asp.net/learn/videos/video-449.aspx и отформатировать каждое значение строки в моем DataTable для CSV, используя следующий код старайтесь избегать потенциально проблемного текста:

private static string FormatForCsv(object value)
        {
            var stringValue = value == null ? string.Empty : value.ToString();
            if (stringValue.Contains("\"")) { stringValue = stringValue.Replace("\"", "\"\""); }
            return "\"" + stringValue + "\"";
        }

Для тех, кому интересно это, я в основном заключаю каждое значение в кавычки, а также избегаю любых существующих кавычек, делая их двойными кавычками. * Т.е. 1006 *

My Dog => "My Dog"
My "Happy" Dog => "My ""Happy"" Dog"

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

Редактировать: Это решение хорошо зарекомендовало себя на производстве для тысяч записей.

0 голосов
/ 01 сентября 2009

ОК, я думаю, вы говорите слишком много строк, чтобы сделать DataReader, а затем циклически проходите, чтобы создать файл cvs. Единственный работающий способ - запустить:

SQLCMD -S MyInstance -E -d MyDB -i MySelect.sql -o MyOutput.csv -s

Чтобы узнать, как запустить это из кода ASP.Net, см. здесь. Затем, как только это будет сделано, ваша страница ASP.Net продолжит:

    string fileName = "MyOutput.csv";
    string filePath = Server.MapPath("~/"+fileName);
    Response.Clear();        
    Response.AppendHeader("content-disposition", 
"attachment; filename=" + fileName);        
    Response.ContentType = "application/octet-stream";        
    Response.WriteFile(filePath);        
    Response.Flush();        
    Response.End();    

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

0 голосов
/ 01 сентября 2009

Почему бы не позволить им пролистать данные, возможно, отсортировав их перед подкачкой, а затем дать им кнопку, чтобы просто получить все как файл cvs.

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

Итак, для cvs вам просто нужно использовать другой запрос LINQ, чтобы получить все строки, а затем начать их сохранять, разделяя каждую ячейку разделителем, обычно запятой или табуляцией. Это может быть что-то выбранное пользователем, возможно.

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