Является ли чрезмерное использование DataTable плохой?

Недавно мне было предложено помочь другой команде в создании веб-сайта ASP.NET. У них уже есть значительный код написания кода - мне было специально предложено создать несколько отдельных страниц для сайта.

При изучении кода для остальной части сайта количество построенных DataTables выскочило на меня. Будучи относительно новым в этой области, я никогда не работал над приложением, которое использует базу данных так же сильно, как этот сайт, поэтому я не уверен, насколько это распространено. Кажется, что всякий раз, когда данные запрашиваются из нашей базы данных, результаты сохраняются в DataTable. Этот DataTable обычно передается сам по себе или передается конструктору. Классы, инициализированные с помощью DataTable, всегда присваивают DataTable частному/защищенному полю, однако только некоторые из этих классов реализуют IDisposable. Фактически, в тысячах строк кода, которые я просматривал до сих пор, мне еще предстоит увидеть метод Dispose, вызываемый в DataTable.

Во всяком случае, это не кажется хорошим ООП. Это то, о чем я должен беспокоиться? Или я просто уделяю больше внимания деталям, чем должен? Предполагая, что вы самые опытные разработчики, чем я, как бы вы себя чувствовали или реагировали, если бы кто-то, кто был просто назначен вам помочь на вашем сайте, подошел к вам по поводу этой "проблемы"?

Ответы

Ответ 1

Datatables можно использовать для добра и зла.

Допустимое использование

Я бы счел приемлемым использование данных datatable или datarow:

public class User
{
    private DataRow Row { get; set; };
    public User(DataRow row) { this.Row = row; }

    public string UserName { get { return (string)Row["Username"]; } }
    public int UserID { get { return (int)Row["UserID"]; } }
    public bool IsAdmin { get { return (bool)Row["IsAdmin"]; } }
    // ...
}

Класс выше нормально, потому что он отображает DataRow в класс типов. Вместо того, чтобы работать со строками и нетипизированными datarows, теперь у вас есть реальные типы данных и intellisense, чтобы помочь вам. Кроме того, если ваша схема базы данных изменяется, вы можете изменить имя столбца в своем объекте, вместо того, чтобы изменять имя столбца всюду по его использованию. Наконец, вы можете сопоставить уродливые имена столбцов, такие как "dtaccount_created", с свойством "AccountCreated".

Конечно, действительно нет веских оснований для написания этого класса-оболочки, поскольку Visual Studio автоматически генерирует типизированные наборы данных для вас. Или, в качестве альтернативы, хороший ORM, такой как NHibernate, позволяет вам определять классы, похожие на приведенные выше.

Должны ли вы использовать простой старый ADO.NET, типизированные наборы данных или полноценный ORM, зависит от требований и сложности вашего приложения. Трудно сказать, делает ли ваша команда правильную вещь, на самом деле видя какой-то образец кода.

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

Неприемлемое использование

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

Основная проблема с datatables: они не печатаются, поэтому вы не можете делать ничего полезного с ними, не давая им строку и бросая любой предмет загадки, который они содержат, в правильный тип. Кроме того, реорганизация имени столбца почти невозможно автоматизировать, поскольку они основаны на строках, поэтому вы не можете полагаться на intellisense, чтобы помочь вам написать правильный код, и вы не можете ловить ошибки во время компиляции.

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

Ответ 2

Это определенно то, о чем вам следует беспокоиться - см. связанный пост о важности Disposing DataTables.

Таблицы данных являются финализированными: если вы не активно их утилизируете, они висят гораздо дольше, чем коллекции Gen0 и убивают память.

Чтобы измерить степень ущерба в приложении, вы можете взять дамп памяти с помощью WinDbg и посмотреть на количество экземпляров DataTable (! dumpheap -stat-type System.Data.DataTable) затем посмотрите наибольшие таблицы данных в памяти.

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

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

Ответ 3

На очень высоком уровне архитектура системы программного обеспечения может быть охарактеризована как использование одного из нескольких "шаблонов уровня предприятия", Transaction script, Таблица Model, Модель домена или Уровень обслуживания. Если система, которую вы просматриваете, использует шаблон таблицы модели, то вы ожидаете большего использования DataTables и DataSets, чем, например, в системе, которая была разработана с использованием модели домена или одного из других шаблонов.

Однако, поскольку методологии разработки программных систем развивались в течение последних нескольких лет, как правило, понималось, что сложные системы не очень хорошо используют архитектуры Transaction script или Table Model. Обычно это связано с тем, что в системах, разработанных с использованием этих шаблонов, функциональность, как правило, гораздо более переплетена и взаимосвязана, а по мере роста сложности объем функциональной или модульной взаимозависимости растет экспоненциально и становится слишком сложным для управления очень быстро. Таким образом, в зависимости от того, насколько сложна ваша конкретная система, да, вы должны быть подозрительными, если DataSets и/или DataTables используются во многих слоях системы. Это может быть признаком того, что разработчик системы использовал/использовал Табличную модель (сознательно или бессознательно), где он должен использовать архитектуру Domain Model или Service Layer.

Ответ 4

да, я был бы здесь осторожен...

Мне пришлось присматривать за веб-приложением vb.net около 2 месяцев, прежде чем я смог переписать все это на С#.... Мне нравится С#, VB заставляет меня хотеть бросить...

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

Хуже того, были моменты, когда он фактически удалял DataTable в сеанс... без всякой причины.

DataTables и т.д. замечательны, но используйте их только в том случае, если вам действительно нужно их использовать. Разработчик был soo плохой, что на странице поиска он фактически сбросил все 5000 продуктов из базы данных в datatable, а затем выполнил поиск в datatable вместо выполнения поиска в хранимой процедуре (то есть на SQL SERVER)

Ответ 5

Использование DataTable может быть ленивым/неэффективным способом хранения данных. При этом значительные накладные расходы. Вы правы, чтобы беспокоиться, хотя разработчик (разработчики) может иметь реальную проблему, слыша, как плохо они разработали это приложение. Будет ли руководство позади вас, в целях создания продукта лучшего качества? Будет ли связанная с этим задержка в развитии тем, что они могут принять?