Лучший способ создать модель данных с динамическим количеством свойств в .NET - PullRequest
3 голосов
/ 29 августа 2011

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

Итак, я добавил в запрос параметр, который указывает свойства, которые вы хотите вернуть, и только эти данные будут извлечены из БД.

Обычный запрос вернет список из 1000 - 10000 строк. Моя большая проблема сейчас в том, как их эффективно вернуть.

Данные будут использоваться "внутренне" в моем .NET-проекте, но также могут быть сериализованы в XML и JSON, и поэтому я не хочу иметь 98 пустых свойств, хотя на самом деле их всего 2 заполнены данными.

Итак, какую методику (в случае производительности и «размера накладных расходов») лучше всего использовать для создания этой модели?

Обновление: Таким образом, собственность может иметь три состояния. Если его никогда не запрашивали, его нужно каким-то образом удалить, а если его запрашивали, оно должно быть либо нулевым, либо фактическим значением.

Ответы [ 2 ]

3 голосов
/ 29 августа 2011

Хотя я согласен с тем, что ответ Андрея удобен, он определенно может повлиять на производительность.Если ваши данные плоские (и это так, поскольку вы в конечном итоге извлекаете данные из базы данных), то у вас может быть IEnumerable<IDictionary<string, object>>, где каждая строка в IEnumerable<T> равна IDictionary<string, object> содержит значения из строки.

Это более громоздко для начала, но является динамическим;добавление или удаление атрибутов из результирующего набора будет по-прежнему работать.

Это также более производительно, так как у вас не будет (1,000 to 10,000) * N вызовов для отражения (от 1000 до 10000) строк, раз N,количество атрибутов в каждой строке (если у вас есть 100 атрибутов в строке, то это 100 000 - 1 000 000 вызовов Reflection, которые будут суммироваться).В конечном итоге DynamicDictionary сохраняет пары ключ / значение в справочной таблице, но для доступа к справочной таблице используется Reflection (оптимизированная с помощью DLR, но все еще в ее основе).

И вы знаете что это за свойства (вы сказали, что используете его для своего проекта, поэтому у вас есть , чтобы узнать, какие свойства вы хотите использовать).Для этого вы действительно должны использовать строго типизированный объект передачи данных со всеми свойствами, которые могут иметь значение null, которые представляют значения из базы данных;все, что является нулевым или не существует в наборе результатов, устанавливается равным нулю.Значения, которые не существуют в результирующем наборе, никогда не устанавливаются.

Таким образом, у вас нет Reflection, вы получаете проверку типов во время компиляции (что очень важно, используя DynamicObject приведет к исключениям времени выполнения) и лучшей производительности.

Сериализация в XML или JSON проста с любым из этих подходов, вы просто сериализуете нулевые значения или не сериализуете свойство вообще (еслииспользуя XML, просто убедитесь, что ваша схема поддерживает элементы в качестве параметров).

3 голосов
/ 29 августа 2011

Рассмотрите возможность использования DynamicDictionary (см. Раздел «Примеры» в документации для класса System.Dynamic.DynamicObject), где DynamicDictionary является производным от класса DynamicObject с возможностью получать / устанавливать свойства ввремя выполнения.

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

    // Creating a dynamic dictionary.
    dynamic person = new DynamicDictionary();

    // Adding new dynamic properties. 
    // The TrySetMember method is called.
    person.FirstName = "Ellen";
    person.LastName = "Adams";

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

Сериализация / десериализация с XML / JSON не должна быть проблемой здесь.

...