Заполнение и использование динамических классов в C # /. NET 4.0 - PullRequest
1 голос
/ 23 апреля 2010

В нашем приложении мы рассматриваем использование динамически генерируемых классов для хранения большого количества наших данных. Причиной этого является то, что у нас есть клиенты с таблицами, которые имеют разную структуру. Таким образом, у вас может быть таблица клиента под названием «DOG» (только что составленная), которая содержит столбцы «DOGID», «DOGNAME», «DOGTYPE» и т. Д. Клиент №2 может иметь ту же таблицу «DOG» со столбцами » DOGID "," DOG_FIRST_NAME "," DOG_LAST_NAME "," DOG_BREED "и т. Д. Мы не можем создавать классы для них во время компиляции, так как клиент может изменить схему таблицы в любое время.

На данный момент у меня есть код, который может генерировать класс "DOG" во время выполнения, используя отражение. Я пытаюсь понять, как заполнить этот класс из DataTable (или какого-либо другого механизма .NET) без чрезмерных потерь производительности. У нас есть одна таблица, которая содержит ~ 20 столбцов и ~ 50 тыс. Строк. Выполнение foreach по всем строкам и столбцам для создания коллекции занимает около 1 минуты, что слишком много.

Я пытаюсь найти решение, которое является слишком сложным, или я на правильном пути? Кто-нибудь еще испытывал такую ​​проблему? Создание динамических классов было решением, которое разработчик из Microsoft предложил. Если мы сможем просто заполнить эту коллекцию и использовать ее эффективно, я думаю, что она может сработать.

Ответы [ 3 ]

3 голосов
/ 23 апреля 2010

То, что вы пытаетесь сделать, будет довольно сложно в .NET 3.5. Возможно, вам лучше создать тип с помощью словаря <> пар ключ / значение для данных в вашей модели.

Если вы можете использовать .NET 4.0, вы можете посмотреть на , используя dynamic и ExpandoObject . Ключевое слово dynamic позволяет создавать ссылки на действительно динамические объекты - ExpandoObject позволяет легко добавлять свойства и методы на лету. Все без сложной рефлексии или логики кода. Преимущество динамических типов состоит в том, что DLR выполняет некоторое сложное кэширование информации привязки во время выполнения, чтобы типы могли быть более производительными, чем позволяет регулярное отражение.

Если все, что вам нужно сделать, это загрузить карту, сопоставить данные с существующими типами, то вам следует рассмотреть возможность использования чего-то вроде EntityFramework или NHibernate для обеспечения поведения ORM для ваших типов.

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

1 голос
/ 06 июля 2011

Проверьте PicoPoco и Massive. Это микро ОРМС. (легковесные платформы ORM с открытым исходным кодом), которые вы используете, просто копируя один файл кода в ваш проект.

Massive использует ExpandoObject и выполняет преобразования из IDataRecord в ExpandoObject, которые, я думаю, именно то, что вам нужно.

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

1 голос
/ 23 апреля 2010

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

Мне любопытно, как вы будете использовать этот класс, если члены не известны во время компиляции? Возможно, вам лучше использовать простой DataTable для этого сценария?

...