Метаданные в среде.Net. Метаданные и валидация модели. Метаданные в мировой сети

Атрибуты

Разработчики могут добавлять метаданные в свой код благодаря атрибутам . Существует два типа (две формы) атрибутов: атрибуты, которые определены в среде CLR (т. н. англ. pseudo custom attributes ), и пользовательские атрибуты (англ. custom attributes ), создаваемые пользователем для добавления в код дополнительных сведений . С точки зрения разработчика оба типа имеют одинаковый синтаксис . Атрибуты в коде являются по сути сообщениями компилятору для создания метаданных. В CIL метаданные (такие как например, модификаторы наследования, модификаторы области видимости), а также почти все, что не является кодом операции или потоками, также помечаются как атрибуты.

Пользовательский атрибут представляет собой обычный класс , наследующий от класса Attribute . Такой атрибут может быть использован для любого метода, свойства, класса или сборки целиком при использовании следующего синтаксиса: [ИмяАтрибута (необязательный параметр , дополнительные пары имя=значение )] . Например:

Пользовательские атрибуты весьма широко используются в платформе.NET Framework. Windows Communication Framework использует атрибуты для определения сервисных контрактов, ASP.NET использует их для предоставления методов как веб-служб , LINQ к SQL использует их для привязки классов к нижележащим реляционным схемам, Visual Studio использует их для группировки свойств объекта, разработчики классов указывают категорию для класса объекта при помощи пользовательского атрибута . Пользовательские атрибуты обрабатываются кодом приложения, а не CLR. Когда компилятор находит пользовательский атрибут, то он создает пользовательские метаданные, нераспознаваемые средой CLR. Разработчик должен реализовать код для чтения и обработки метаданных. В качестве примера, атрибут, показанный в примере выше, может быть обработан следующим кодом:

Class CustomAttribute : Attribute { private int paramNumber = 0 ; private string comment = "" ; public CustomAttribute() { } public CustomAttribute(int num) { paramNumber = num; } public String Comment { set { comment = value ; } } }

Имя класса связано с именем атрибута. Компилятор среды разработки Visual C# автоматически добавляет строку « Attribute » в конец каждого имени атрибута. Как следствие, каждое имя атрибута класса должно оканчиваться такой строкой, но вполне допускается и определение атрибута без суффикса Attribute . При добавлении атрибута к какому-либо элементу компилятор ищет и по указанному имени и имени со словом Attribute на конце, то есть если написать , то компилятор будет искать и Custom и CustomAttribute . Если же они оба существуют, то компилятор сообщит об ошибке. Во избежание неоднозначности имена атрибутов могут помечаться префиксом « @ », в результате чего [@Custom] будет не то же самое что и CustomAttribute . Использование атрибута вызывает конструктор класса, причем поддерживаются и перегруженные конструкторы. Пары «имя-значение» привязываются к свойствам, при этом «имя» обозначает имя свойства, а «значение» - присвоенное значение свойства.

Иногда появляется путаница относительно добавления атрибута. Например, в следующем коде непонятно, что именно обозначается как «orange»:

В данном случае «orange» может означать какой-нибудь тестовый метод ExampleMethod , его возвращаемое значение или всю сборку целиком. В этом случае компилятор по умолчанию попытается обработать атрибут как атрибут метода. Если это не то, что предполагалось автором кода, или автор просто захотел сделать код более понятным, то допускается указание цели атрибута . Написание укажет на то, что возвращаемым значением будет «апельсин», укажет на всю сборку целиком. Допустимыми целями являются: сборка (assembly), поле (field), событие (event), метод (method), модуль (module), параметр (param), свойство (property), возвращаемое значение (return) и тип (type).

Заранее определённые атрибуты используются так же как и обычные атрибуты, но у них нет настраиваемого обработчика, поскольку компилятор содержит в себе уже встроенное описание таких атрибутов и обрабатывает код в зависимости от установленной метки. Такие атрибуты как Serializable и Obsolete реализуются именно как заранее определённые атрибуты. Заранее определённые атрибуты не должны использоваться ассемблером ILASM, поскольку у него есть собственный синтаксис для описания метаданных.

Хранение метаданных

Сборки содержат в себе таблицы метаданных, описанные в спецификации CIL. Таблицы метаданных могут иметь ноль или более записей (вхождений), причем позиция записи определяет её индекс. Когда код CIL использует метаданные, то он делает это по меткам метаданных. Это 32-битное значение, в котором первые 8 бит содержат данные, идентифицирующие соответствующую таблицу метаданных, а оставшиеся 24 бита определяют индекс метаданных в таблице. SDK платформы содержит пример, именуемый metainfo (рус. метаинформация ), перечисляющий в виде списка таблицы метаданных в сборке. Однако, эта информация довольно редко используется разработчиком. Метаданные в сборке можно просматривать при помощи утилиты ILDASM, поставляемой в составе.NET Framework SDK.

Отражение

Примечания

См. также

  • Аннотации в Java

Ссылки

  • Атрибуты в C# (рус.)
  • Метаданные в среде.Net (рус.)

Wikimedia Foundation . 2010 .

Последнее обновление: 31.10.2015

При работе с моделью в MVC большее значение играют метаданные. Они позволяют указать некоторую дополнительную информацию об объекте, например, о том, как отображать его свойства в представлении, или о том, как осуществлять валидацию вводимых данных.

Аннотации данных для отображения свойств

Аннотации данных представляют собой атрибуты, которые вы можете найти в пространстве имен System.ComponentModel.DataAnnotations (хотя несколько атрибутов определено в других пространствах).

Атрибут Display

Итак, предположим у нас имеется некоторая модель Book:

Public class Book { public int Id { get; set; } public string Name { get; set; } public string Author { get; set; } public int Year { get; set; } }

И мы пытаемся получить из базы данных один объект этой модели:

Public class HomeController: Controller { BookContext db = new BookContext(); public ActionResult Index() { var firstBook = db.Books.FirstOrDefault(); return View(firstBook); } }

Используя соответствующий хелпер, мы выводим эту модель представлении: @Html.DisplayForModel() :

@model DataAnnotations.Models.Book @{ ViewBag.Title = "Книга"; } @Html.DisplayForModel()

Обычный код, но тут мы сталкиваемся с проблемой:

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

Конечно, в этом случае мы могли бы использовать @Html.LabelFor для настройки названия для каждого отдельного свойства, но в этом случае у нас бы увеличился в несколько раз объем кода, и мы не смогли бы одной строкой вывести всю информацию о модели. К тому же может потребоваться в нескольких представлениях выводить информацию о модели. Поэтому данный подход не оптимален.

И тут нам на помощь приходят аннотации данных, а именно атрибут Display . Нам достаточно поправить модель, указав у нее параметры отображения:

Using System.ComponentModel.DataAnnotations; ........................................... public class Book { public int Id { get; set; } public string Name { get; set; } public string Author { get; set; } public int Year { get; set; } }

Свойство Name атрибута Display содержит строку, которая будет отображаться вместо имени свойства. Больше нам ничего не надо менять. Запустим и увидим новые названия:

Атрибут HiddenInput

В предыдущем примере у нас осталась одна проблемка - это поле Id. Иногда, конечно, может потребоваться вывод поля Id. Но, например, если бы мы выводили модель в режиме редактирования с помощью хелпера @Html.EditorForModel() , то данное поле было бы доступно для редактирования, что не очень хорошо, особенно когда идентификаторы не должны меняться. Чтобы скрыть это поле мы можем применить атрибут HiddenInput :

Using System.ComponentModel.DataAnnotations; using System.Web.Mvc; ........................................... public class Book { public int Id { get; set; } public string Name { get; set; } public string Author { get; set; } public int Year { get; set; } }

Свойство DisplayValue=false указывает, что надо скрыть данное поле. В итоге вы его не увидите:

При использовании хелперов редактирования (Html.EditorFor/Html.EditorForModel) для данного свойства будет сгенерировано скрытое поле:

Атрибут ScaffoldColumn

При редактировании модели атрибут HiddenInput полностью не скрывает поля, так как мы можем посмотреть исходный код страницы и найти соответствующие поля. Чтобы полностью скрыть свойство от хелперов, используется атрибут ScaffoldColumn :

Public int Id { get; set; }

Теперь хелперы редактирования не увидят данное свойство и не создадут для него даже скрытое поле на странице.

Атрибут DataType

Атрибут DataType позволяет предоставлять среде выполнения информацию об использовании свойства. Например, допустим, у нас есть свойство Password:

Public string Password { get; set; }

Для свойства с атрибутом DataType.Password HTML-хелперы создают элемент ввода, у которого атрибут type имеет значение "password". Тогда в браузере вы при вводе данных вы не увидите вводимые символы, а вместо них будут выводиться точки.

Перечисление DataType может принимать несколько различных значений:

Атрибут UIHint

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

Имеются следующие встроенные шаблоны:

    Boolean

    Хелперы редактирования создают флажок (checkbox) для булевых значений. Для значений типа bool? (nullable) создается элемент select с параметрами True, False и Not Set

    Хелперы отображения генерируют те же элементы html, что и хелперы редактирования, только с атрибутом disabled

    Collection

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

    Decimal

    Хелперы редактирования создают однострочное текстовое поле - элемент input

    EmailAddress

    HiddenInput

    Создается скрытое поле - элемент hidden input

    Html

    Хелперы редактирования создают однострочное текстовое поле.

    Хелперы отображения просто показывают текст

    MultilineText

    Хелперы редактирования создают многострочное текстовое поле (элемент textarea)

    Object

    Хелперы изучают свойства объекта и выбирают наиболее подходящие для него шаблоны.

    Password

    Хелперы редактирования создают текстовое поле для ввода символов с использованием маски

    Хелперы отображения показывают пароль как есть, без использования маски

    String

    Хелперы редактирования создают однострочное текстовое поле

    Хелперы редактирования создают текстовое поле

Например, используем последний шаблон Url:

Public class Book { public int Id { get; set; } public string Name { get; set; } public string Author { get; set; } public int Year { get; set; } }

Тогда мы получим следующий результат:

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

Результат публикации данных в свободном и бесплатном доступе напрямую зависит от их состава и качества. Чем более полными и корректными окажутся публичные данные, тем выше будет эффективность их использования и тем больше пользователей предпочтет поработать с ними.

В отношении любых передаваемых данных, особенно публичных, необходимо всегда оценивать три их ключевых аспекта: состав (содержание), описание (метаданные) и окружение (контекст).

Настоящая публикация продолжает тему открытых, разделяемых и делегируемых данных и относится ко всем этим трем указанным категориям.

Организация данных

Первый важный аспект публичных данных связан с их содержимым и с их внутренней организацией.

Смысл

Всякие хорошие данные обладают некоторым полезным смыслом. Бессмысленная информацию в любом виде непригодна для последующей обработки и анализа в любом виде деятельности с помощью любых инструментов.

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

Учитывая тот факт, что на данные прямое и неотделимое влияние оказывает человеческий фактор, всегда можно говорить о том, что они описывают не объективную реальность, а некоторое понимание человеком той объективной реальности, о которой он целевым образом собирает сведения. Иными словами, данные всегда содержат некую долю субъективности в своем содержимом или в структуре и описывают воспринимаемую модель из заданной предметной области.

Именно тот факт, что данные в той или иной степени описывают некоторый смысл целевой модели, возможен последующий их анализ и выявление важных атрибутов такой модели.

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

На то, какой смысл имеют данные влияет их уровень передела.

Наиболее ценными с этой точки зрения и обладающие неискаженным смыслом являются собранные первичные данные. Чем больше обработок было произведено с данными, тем больше смысл искажается и видоизменяется. Отсюда необходимость явно указывать количество и качество переделов данных.

Структура

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

Но это не всё.

Выбор минимальной целостной и неделимой единицы является субъективным понятием в рамках заданной тематики и целей пользователя.

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

После того, как задано понятие минимальной неделимой единицы данных, возникает и понятие структуры всей совокупности целевых данных. Так для электронной таблицы, единицы данных формируют наборы данных в виде строк или столбцов, а в последующем группируются в таблицы (листы) и наборы таблиц (книги).

Удобно выделять два уровня группировки целостных единиц данных:

  • первичный – группировка (объединение, упорядочивание) непосредственно элементарных неделимых целостных единиц данных;
  • вторичный – группировка (объединение, упорядочивание) первично и вторично сгруппированных единиц данных.
Задаваемая структура данных опирается на некоторое дополнительное определение их характеристик, поэтому прямо или косвенно обуславливает присутствие метаданных.

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

Операции с данными производятся непосредственно с неделимыми целостными единицами или с их группами. Причем даже есть возможность обрабатывать неделимые целостные единицы тем или иным образом создавая из них новые. Например, это позволяет делать функционал электронных таблицы: обрабатывать содержимое отдельной ячейки и разделять её на некие составные элементы, но при этом основной акцент в подобном приложении всё-таки сделан на обработке ячеек как на простейших обрабатываемых элементарных единицах.

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

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

Ещё одна полезная и важная особенность структуры данных, как производная от идентификации заключается в связывании отдельных элементов данных по тем или иным критериям или задачам. Связывание фактически приводит к появлению такого функционала как вторичное структурирование, нелинейное упорядочивание, гиперссылки, альтернативные пути обхода и т.п. Если сопроводить связь некоторыми дополнительными атрибутами, то можно выделить даже особый класс объектов-описателей и выстроить сложные зависимые структуры доселе невообразимых форм и сочетаний. Именно за счет связывания появляется некая динамика в данных.

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

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

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

Формат

В контексте данной публикации «формат» – это способ сохранения данных в физической обособленной единице (файл, запись, таблица, поток) на заданном носителе.

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

  1. Кодировка данных – выбранный способ установки кодов для конечного набора символов или понятий задействованных и допустимых для записи данных. Например, кодировка символов UTF-8 или ASCII.
  2. Нотация данных – выбранный способ формализованной записи упорядоченных данных. Например, CSV или XML.
  3. Схема данных – выбранный способ специальной организации разных элементов данных по предопределенным метаданным. Например, для XML – это выбор XSD, для CSV – это выбор схемы таблицы (полей и связей).
Чем выше слой, тем более он предметно-ориентирован и зависит от смысла данных. На 3-ем слое – схема данных – формат почти полностью смешивается с предметной областью целевых данных.

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

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

Например, если структурирование данных сведено к таблице, то очевидно, что удобно будет её отформатировать, скорее, как CSV, чем как HTML. С другой стороны, задача может быть поставлена так, что выбор будет сделан в пользу XML. Кажется, совсем уж экзотическим, но вполне возможно нотировать таблицу данных и как последовательность команд INSERT (SQL) для каждой из строк.

Для публичных данных наиболее предпочтительным являются простые, свободные и распространенные форматы. Приоритетной, например, для открытых государственных данных выглядит связка: . Причем custom-схема данных часто описывается в «паспорте открытых данных».

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

Вопрос повторного использования данных может быть неверно отнесен к особенностям их форматирования, но это скорее вопрос правильного их структурирования. Именно на уровне структуры цифровых данных появляется возможность связывания и организации ссылок. Формат лишь только определяет фактические правила записи и разрешения ссылок. В том числе формат может задавать или поддерживать «межформатные» правила ссылок, чтобы у пользователя появилась возможность сослаться в одном наборе или элементе данных на другой.

Безусловно машинное чтение данных зависит от формата

При этом понимать «машинное» чтение в отрыве от структуры данных неверно. Ведь речь ведется о возможности прочитать цифровые данные исходя из чтения алгоритмами заданной цифровой структуры. Так в простых сканированных изображениях отсутствует смысловая структура цифровых данных. Да, скан-копия – это несомненно некий упорядоченный поток цифровых данных воспроизводимый специальной программой в изображение, которое понимает человек на своем уровне. Её даже может «распознать» OCR-алгоритм. Но она не имеет заданной структуры данных, что без дополнительной обработки позволяет рассматривать сканированное изображение исключительно в целом как неделимую единицу. Соответственно польза от необработанной скан-копии минимальна. Публикация же сканированных документов в таком случае может быть нацелена исключительно на просмотр человеком, либо на применение особо сложных и производительных инструментов «вычленения» сведений из достоверных исходников.
Сканированные документы или иные изображения могут являться замечательным доказательством первичных данных и даже первоисточником для избирательной ручной их проверки. Если же выложенные в публичном доступе сканированные изображения с ценными данными кто-либо преобразует в массивы читаемых и обрабатываемых данных, то вряд ли сохранится цепочка «бесплатности». Всё-таки, пока, на обработку скан-копий нужны ресурсы. Хотя технологии не стоят на месте, в том числе и технологии инвестирования в масштабные проекты.
Таким образом, даже необработанные изображения могут составлять отдельную категорию публичных данных. И они в любом случае являются машиночитаемыми. Вообще-то, достаточно сложно представить себе нечитаемый машиной цифровой поток байт. Максимум, что может быть предъявлено – это нарушение целостности данных на любом из уровней: на смысловом, на структурном или на одном из слоев формата.

Описание данных

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

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

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


Для целостной передачи публичных данных, самый лучший способ – это сохранять метаданные «внутри» самих данных. То есть таким образом записывать оригинальные цифровые данные, чтобы они параллельно сопровождались некоторыми атрибутами, а структура записи позволяла алгоритмам извлекать заложенные в неё метаданные.

Что достаточно хорошо можно делать, например, в рамках XML-нотации: где разметка уже определяет тип элемента (узел, атрибут, документ), а применение атрибутов и имен пространств открывает возможности для внедрения метаданных. Однако чтение данных совмещенных с их описанием, как минимум, требует овладения более сложными компетенциями и инструментами. Гораздо понятней и очевидней для большинства пользователей получать чистые данные с наименованием и заголовками. Но это в свою очередь вызывает свои проблемы в чтении и понимании данных. До выработки единых и понятных стандартов в этом направлении пока далеко.

Метаданные должны включать:

  1. Описание смысла данных:
    • a. наименование
    • b. краткое описание
    • c. описание предметной области
    • d. точка зрения
    • e. цель сбора и представления данных
    • f. уровень переработки данных
    • g. ограничения по использованию с точки зрения предметной области
    • h. иллюстративные модели и схемы для сложных данных
    • i. тезаурус понятий, связанных с данными (или отсылка к валидному тезаурусу)
    • j. ссылки на источники данных (первичные данные) и на способ сбора данных
    • k. маркировка данных по времени, месту, актуальности, зависимости, значимости и т.д.
    • l. отсылки к контекстным цифровым данным или иным полезным сведениям
    • m. возможные проблемы со смысловой целостностью данных и рекомендованные пути их решения
  2. Описание структуры данных:
    • a. базовые элементы структуры (целостные и неделимые)
    • b. принципы группировки и связывания элементарных и производных единиц данных
    • c. приоритетные и вторичные валидные взаимозависимости элементов структуры данных
    • d. наличие и возможные базовые типа элементов структуры
    • e. отсылка или формализация принципов построения структуры данных или её трансформации
    • f. допустимость внешних ссылок на элементы, входящие в структуру данных
    • g. применяемые стандарты для построения структуры
    • h. ограничения по структуре данных
    • i. возможные проблемы со структурной целостностью данных и рекомендованные пути их решения
  3. Описание формата данных:
    • a. применяемый формат кодирования данных (ссылка или описание)
    • b. применяемый формат нотации данных (ссылка или описание)
    • c. применяемый формат схемы данных (ссылка или описание)
    • d. рекомендуемые инструменты для работы с форматом данных (алгоритмы, спецификации, протоколы, программные пакеты, сервисы и др.)
    • e. особенности применения формата данных
    • f. возможные ошибки и проблемы применения формата данных
    • g. обоснование применения формата данных (по необходимости)
    • h. предусмотренные (проверенные) варианты конвертации в другие форматы
    • i. техническая оценка качества соответствия данных заданному формату (особенно в тех случаях, когда данные могут содержать ошибки форматирования)
    • j. возможные проблемы с целостностью данных на уровне формата и рекомендованные пути их решения
Чем больше и полней формируются метаданные сопровождающие пакет цифровых данных, тем мощнее будет их последующее использование для извлечения полезных знаний и тем результативнее будет обратный эффект от новых знаний на систему, которую описывают исходные данные.

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

Для понимания того, что следует включать в метаданные, можно рассмотреть операции, в которых они фактически применяется или требуются к применению. Вот наиболее важные семь из них с точки зрения двух непосредственно взаимодействующих ролей в рамках public-схемы трансфера данных:

1. Идентификация данных

  • Поставщик назначает наименование и определяет предметную область для набора данных
  • Получатель восстанавливает название, назначение, предметную область и систему взаимодействующих объектов, которую описывает набор данных
2. Аутентификация данных
  • Поставщик задает факторы возможной и допустимой проверки подлинности и качества (в т.ч. релевантности, актуальности, адекватности) публикуемого набора данных
  • Получатель понимает возможный способ проверки подлинности и качества (в т.ч. релевантности, актуальности, адекватности) набора данных и, в случае необходимости, осуществляет проверку
3. Авторизация данных
  • Поставщик определяет и формализует кто является по отношению к набору данных автором, владельцем и издателем, а также устанавливает кому доступны публикуемые данные, на каких условиях и для чего
  • Получатель проверяет и оценивает кто создал, владеет и поставляет набор данных, а также проходит проверку на возможность и целесообразность их использования
4. Оценка данных
  • Поставщик измеряет количество данных (в рамках выбранной структуры и формата) и дает оценку качества данных
  • Получатель изучает установленные объемы данных (в рамках указанной структуры и формата) и проверяет выданную оценку качества данных на предмет возможного использования
5. Ограничения данных
  • Поставщик задает различные ограничения (по смыслу, структуре и формату) для публикуемого набора данных и издает данные в соответствии с ограничениями
  • Получатель выясняет какие ограничения (по смыслу, структуре и формату) наложены на набор данных и работает с данными с их учетом
6. Передача данных
  • Поставщик комплектует данные в целостный набор и в рамках установленных условий (контракта трансфера данных) передает их напрямую или открывает к ним доступ
  • Получатель принимает напрямую или загружает из открытого доступа скомплектованный целостный набор данных по установленным условиям
7. Обработка данных
  • Поставщик предварительно (перед публикацией) обрабатывает данные в набор в соответствии с имеющейся задачей публикации
  • Получатель обрабатывает принятые данные для своих целей в рамках известных ему обстоятельств публикации

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

Они определяют формат набора, особенности применения формата, схему данных, кодировку, организующую структуру, назначение и особенности состава, предметную область и применимость данных к той или иной тематической задаче, проверяют качество данных и их актуальность и делают ещё много разных подобных вещей. Например, даже тексты SQL-запросов можно делать, имея только схему таблиц и не имея непосредственно данные из этих таблиц.


Качество публичных данных начинается с качества их метаданных.

Окружение данных

Особую роль в отдельных ситуациях начинает играть третий аспект публичных данных – окружение.

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

В пространстве публичных данных – контекстом для заданного набора будут являются все иные данные с которыми их смогут корректно связать аналитики по тем или иным основаниям.
Правильно указать контекст можно только если для основных данных правильно задана предметная область и их назначение.

Контекстные связываются с основными данные несколькими способами:

  1. Прямое ссылочное связывание – через указание прямых ссылок на сторонние наборы данных, которые публикуются тем же издателем или публикуются иными лицами в открытом доступе. Контекст служит в этом ключе официальным расширением данных. Очевидно, что прямое связывание публичных данных с закрытыми или платными является примером не совсем добросовестного издателя.
  2. Косвенное предметное связывание – через определение для основных данных названия, тематики, назначения, релевантности и актуальности. Пользователь самостоятельно изучает заданную предметную область и осуществляет поиск данных, которые составляют интересующий его контекст. Кроме очевидных примеров предметного связывания, стоит упомянуть варианты математического связывания: по показателям распределения, частотности или иным. А также варианты связывания по сходным атрибутам или по идентичным основаниям.
  3. Связывание имплементацией – через включение в основные данные фрагментов других данных в результате чего устанавливается неочевидная ссылочная или предметная связь. Если получатель достаточно четко понимает «внедрение» контекста в основу, то он также четко понимает суть контекстных данных. Достаточно часто подобный способ связывания основан на включении в основные данные уникальных или условно-уникальных идентификаторов контекстных данных. В отличии от прямого ссылочного связывания, связывание имплементацией не предусматривает включение явной адресации на элементы контекстных данных и категорически не предусматривает какие-либо ссылки на контекстные наборы. А в отличии от косвенного предметного связывания, имплементация все-таки предусматривает указание определенных идентифицирующих фрагментов контекста в основу.
Любые данные можно с той или иной точки зрения считать контекстом по отношению к основным. Это субъективный аспект аналитики. Весь вопрос заключается в решаемых задачах и целесообразности.

Постоянное разукрупнение анализируемого массива данных путем поиска и подключения к нему дополнительного окружения не может считаться нормой, если является самоцелью. Поэтому рациональным подходом можно назвать обстоятельную работу по тщательному планированию исследования данных в рамках которого обозначают и придерживаются ограниченного набора. Вопрос «а какие данные ещё нужны?» должен задаваться на ключевых этапах анализа в случаях, когда действительно требуется расширить смысловой фронт исследований.

Контекст редко принимается во внимание при публикации данных или при их использовании, либо воспринимается как некое само собой разумеющееся действие по увеличение массива данных. Однако именно неограниченная возможность расширения основы контекстом и многочисленные варианты комбинирования данных позволяют получить преимущество публичного использования данных перед закрытым . В этой связи приоритетным является развитие хранилищ общедоступных и общезначимых цифровых данных, которые составляют контекст для любых данных в заданной предметной области. Например, при работе с экономическими данными может оказаться крайне полезным иметь в свободном доступе общеприменимые справочники, классификаторы, каталоги (например ОКВЭД, КЛАДР, БИК, ЕГРЮЛ и т.п.)

В этих же целях крайне полезны создаваемые и развиваемые тематические «порталы» и «хабы» открытых данных.

Теги: Добавить метки

Последнее обновление: 31.10.2015

При работе с моделью в MVC большее значение играют метаданные. Они позволяют указать некоторую дополнительную информацию об объекте, например, о том, как отображать его свойства в представлении, или о том, как осуществлять валидацию вводимых данных.

Аннотации данных для отображения свойств

Аннотации данных представляют собой атрибуты, которые вы можете найти в пространстве имен System.ComponentModel.DataAnnotations (хотя несколько атрибутов определено в других пространствах).

Атрибут Display

Итак, предположим у нас имеется некоторая модель Book:

Public class Book { public virtual int Id { get; set; } public virtual string Name { get; set; } public virtual string Author { get; set; } public virtual int Year { get; set; } }

И мы пытаемся получить из базы данных один объект этой модели:

Public class HomeController: Controller { private BookContext db = new BookContext(); public ActionResult Index() { var firstBook = db.Books.ToList().First(); return View(firstBook); } }

Используя соответствующий хелпер, мы выводим эту модель представлении: @Html.DisplayForModel() :

@model DataAnnotations.Models.Book @{ ViewBag.Title = "Книга"; } @Html.DisplayForModel()

Обычный код, но тут мы сталкиваемся с проблемой:

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

Конечно, в этом случае мы могли бы использовать @Html.LabelFor для настройки названия для каждого отдельного свойства, но в этом случае у нас бы увеличился в несколько раз объем кода, и мы не смогли бы одной строкой вывести всю информацию о модели. К тому же может потребоваться в нескольких представлениях выводить информацию о модели. Поэтому данный подход не оптимален.

И тут нам на помощь приходят аннотации данных, а именно атрибут Display . Нам достаточно поправить модель, указав у нее параметры отображения:

Using System.ComponentModel.DataAnnotations; ........................................... public class Book { public virtual int Id { get; set; } public virtual string Name { get; set; } public virtual string Author { get; set; } public virtual int Year { get; set; } }

Свойство Name атрибута Display содержит строку, которая будет отображаться вместо имени свойства. Больше нам ничего не надо менять. Запустим и увидим новые названия:

Атрибут HiddenInput

В предыдущем примере у нас осталась одна проблемка - это поле Id. Иногда, конечно, может потребоваться вывод поля Id. Но, например, если бы мы выводили модель в режиме редактирования с помощью хелпера @Html.EditorForModel() , то данное поле было бы доступно для редактирования, что не очень хорошо, особенно когда идентификаторы не должны меняться. Чтобы скрыть это поле мы можем применить атрибут HiddenInput :

Using System.ComponentModel.DataAnnotations; using System.Web.Mvc; ........................................... public class Book { public virtual int Id { get; set; } public virtual string Name { get; set; } public virtual string Author { get; set; } public virtual int Year { get; set; } }

Свойство DisplayValue=false указывает, что надо скрыть данное поле. В итоге вы его не увидите:

При использовании хелперов редактирования (Html.EditorFor/Html.EditorForModel) для данного свойства будет сгенерировано скрытое поле:

Атрибут ScaffoldColumn

При редактировании модели атрибут HiddenInput полностью не скрывает поля, так как мы можем посмотреть исходный код страницы и найти соответствующие поля. Чтобы полностью скрыть свойство от хелперов, используется атрибут ScaffoldColumn :

Public virtual int Id { get; set; }

Теперь хелперы редактирования не увидят данное свойство и не создадут для него даже скрытое поле на странице.

Атрибут DataType

Атрибут DataType позволяет предоставлять среде выполнения информацию об использовании свойства. Например, допустим, у нас есть свойство Password:

Public string Password { get; set; }

Для свойства с атрибутом DataType.Password HTML-хелперы создают элемент ввода, у которого атрибут type имеет значение "password". Тогда в браузере вы при вводе данных вы не увидите вводимые символы:

Перечисление DataType может принимать несколько различных значений:

Атрибут UIHint

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

Имеются следующие встроенные шаблоны:

    Boolean

    Хелперы редактирования создают флажок (checkbox) для булевых значений. Для значений типа bool? (nullable) создается элемент select с параметрами True, False и Not Set

    Хелперы отображения генерируют те же элементы html, что и хелперы редактирования, только с атрибутом disabled

    Collection

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

    Decimal

    Хелперы редактирования создают однострочное текстовое поле - элемент input

    EmailAddress

    HiddenInput

    Создается скрытое поле - элемент hidden input

    Html

    Хелперы редактирования создают однострочное текстовое поле.

    Хелперы отображения просто показывают текст

    MultilineText

    Хелперы редактирования создают многострочное текстовое поле (элемент textarea)

    Object

    Хелперы изучают свойства объекта и выбирают наиболее подходящие для него шаблоны.

    Password

    Хелперы редактирования создают текстовое поле для ввода символов с использованием маски

    Хелперы отображения показывают пароль как есть, без использования маски

    String

    Хелперы редактирования создают однострочное текстовое поле

    Хелперы редактирования создают текстовое поле

Например, используем последний шаблон Url:

Public class Book { public virtual int Id { get; set; } public virtual string Name { get; set; } public virtual string Author { get; set; } public virtual int Year { get; set; } }

Этого метода.

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

Атрибуты

Разработчики могут добавлять метаданные в свой код благодаря атрибутам . Существует два типа (две формы) атрибутов: атрибуты, которые определены в среде CLR (т. н. англ. pseudo custom attributes ), и пользовательские атрибуты (англ. custom attributes ), создаваемые пользователем для добавления в код дополнительных сведений . С точки зрения разработчика оба типа имеют одинаковый синтаксис . Атрибуты в коде являются по сути сообщениями компилятору для создания метаданных. В CIL метаданные (такие как например, модификаторы наследования, модификаторы области видимости), а также почти все, что не является кодом операции или потоками, также помечаются как атрибуты.

Пользовательский атрибут представляет собой обычный класс , наследующий от класса Attribute . Такой атрибут может быть использован для любого метода, свойства, класса или сборки целиком при использовании следующего синтаксиса: [ИмяАтрибута (необязательный параметр , дополнительные пары имя=значение )] . Например:

Пользовательские атрибуты весьма широко используются в платформе.NET Framework. Windows Communication Framework использует атрибуты для определения сервисных контрактов, ASP.NET использует их для предоставления методов как веб-служб , LINQ к SQL использует их для привязки классов к нижележащим реляционным схемам , Visual Studio использует их для группировки свойств объекта, разработчики классов указывают категорию для класса объекта при помощи пользовательского атрибута . Пользовательские атрибуты обрабатываются кодом приложения, а не CLR. Когда компилятор находит пользовательский атрибут, то он создает пользовательские метаданные, нераспознаваемые средой CLR. Разработчик должен реализовать код для чтения и обработки метаданных. В качестве примера, атрибут, показанный в примере выше, может быть обработан следующим кодом:

class CustomAttribute: Attribute { private int paramNumber = 0; private string comment = ""; public CustomAttribute() { } public CustomAttribute(int num) { paramNumber = num; } public String Comment { set { comment = value; } } }

Имя класса связано с именем атрибута. Компилятор среды разработки Visual C# автоматически добавляет строку « Attribute » в конец каждого имени атрибута. Как следствие, каждое имя атрибута класса должно оканчиваться такой строкой, но вполне допускается и определение атрибута без суффикса Attribute . При добавлении атрибута к какому-либо элементу компилятор ищет и по указанному имени и имени со словом Attribute на конце, то есть если написать , то компилятор будет искать и Custom и CustomAttribute . Если же они оба существуют, то компилятор сообщит об ошибке. Во избежание неоднозначности имена атрибутов могут помечаться префиксом « @ », в результате чего [@Custom] будет не то же самое что и CustomAttribute . Использование атрибута вызывает конструктор класса, причем поддерживаются и перегруженные конструкторы. Пары «имя-значение» привязываются к свойствам, при этом «имя» обозначает имя свойства, а «значение» - присвоенное значение свойства.

Иногда появляется путаница относительно добавления атрибута. Например, в следующем коде непонятно, что именно обозначается как «orange»:

В данном случае «orange» может означать какой-нибудь тестовый метод ExampleMethod , его возвращаемое значение или всю сборку целиком. В этом случае компилятор по умолчанию попытается обработать атрибут как атрибут метода. Если это не то, что предполагалось автором кода, или автор просто захотел сделать код более понятным, то допускается указание цели атрибута . Написание укажет на то, что возвращаемым значением будет «апельсин», укажет на всю сборку целиком. Допустимыми целями являются: сборка (assembly), поле (field), событие (event), метод (method), модуль (module), параметр (param), свойство (property), возвращаемое значение (return) и тип (type).

Заранее определённые атрибуты используются так же как и обычные атрибуты, но у них нет настраиваемого обработчика, поскольку компилятор содержит в себе уже встроенное описание таких атрибутов и обрабатывает код в зависимости от установленной метки. Такие атрибуты как Serializable и Obsolete реализуются именно как заранее определённые атрибуты. Заранее определённые атрибуты не должны использоваться ассемблером ILASM, поскольку у него есть собственный синтаксис для описания метаданных.

Хранение метаданных

Сборки содержат в себе таблицы метаданных, описанные в спецификации CIL. Таблицы метаданных могут иметь ноль или более записей (вхождений), причем позиция записи определяет её индекс. Когда код CIL использует метаданные, то он делает это по меткам метаданных. Это 32-битное значение, в котором первые 8 бит содержат данные, идентифицирующие соответствующую таблицу метаданных, а оставшиеся 24 бита определяют индекс метаданных в таблице. SDK платформы содержит пример, именуемый metainfo (рус. метаинформация ), перечисляющий в виде списка таблицы метаданных в сборке. Однако, эта информация довольно редко используется разработчиком. Метаданные в сборке можно просматривать при помощи утилиты ILDASM (Intermediate Language Disassembler), поставляемой в составе.NET Framework SDK.

Отражение

Отражение - это интерфейс программирования приложений (API), используемый для чтения метаданных.NET. API отражения предоставляет возможность реализации в первую очередь логического просмотра метаданных, нежели точный просмотр, обеспечиваемый инструментами типа metainfo. Отражение в версии 1.1 платформы.NET может быть использовано для проверки описания классов и их членов, а также вызова методов. Однако, оно не позволяет среде исполнения получать доступ к CIL ради метода. Версия 2.0 платформы позволяет получать метод из CIL.

Прочие инструменты для работы с метаданными

Помимо пространства имён System.Reflection существуют также и другие инструменты, которые могут применяться для работы с метаданными. Microsoft .NET Framework поставляется совместно с библиотекой для манипуляции метаданными CLR, реализуемой в машинном коде . Для извлечения и манипуляции метаданными могут использоваться и сторонние инструменты, такие как и .

Напишите отзыв о статье "Метаданные в.NET"

Примечания

См. также

Ссылки

  • (рус.)
  • (рус.)

Отрывок, характеризующий Метаданные в.NET

– Нет, уехали.
«Как бы мне не отвечать за промедление! Вот досада!» – думал офицер. Он объездил весь лагерь. Кто говорил, что видели, как Ермолов проехал с другими генералами куда то, кто говорил, что он, верно, опять дома. Офицер, не обедая, искал до шести часов вечера. Нигде Ермолова не было и никто не знал, где он был. Офицер наскоро перекусил у товарища и поехал опять в авангард к Милорадовичу. Милорадовича не было тоже дома, но тут ему сказали, что Милорадович на балу у генерала Кикина, что, должно быть, и Ермолов там.
– Да где же это?
– А вон, в Ечкине, – сказал казачий офицер, указывая на далекий помещичий дом.
– Да как же там, за цепью?
– Выслали два полка наших в цепь, там нынче такой кутеж идет, беда! Две музыки, три хора песенников.
Офицер поехал за цепь к Ечкину. Издалека еще, подъезжая к дому, он услыхал дружные, веселые звуки плясовой солдатской песни.
«Во олузя а ах… во олузях!..» – с присвистом и с торбаном слышалось ему, изредка заглушаемое криком голосов. Офицеру и весело стало на душе от этих звуков, но вместе с тем и страшно за то, что он виноват, так долго не передав важного, порученного ему приказания. Был уже девятый час. Он слез с лошади и вошел на крыльцо и в переднюю большого, сохранившегося в целости помещичьего дома, находившегося между русских и французов. В буфетной и в передней суетились лакеи с винами и яствами. Под окнами стояли песенники. Офицера ввели в дверь, и он увидал вдруг всех вместе важнейших генералов армии, в том числе и большую, заметную фигуру Ермолова. Все генералы были в расстегнутых сюртуках, с красными, оживленными лицами и громко смеялись, стоя полукругом. В середине залы красивый невысокий генерал с красным лицом бойко и ловко выделывал трепака.
– Ха, ха, ха! Ай да Николай Иванович! ха, ха, ха!..
Офицер чувствовал, что, входя в эту минуту с важным приказанием, он делается вдвойне виноват, и он хотел подождать; но один из генералов увидал его и, узнав, зачем он, сказал Ермолову. Ермолов с нахмуренным лицом вышел к офицеру и, выслушав, взял от него бумагу, ничего не сказав ему.
– Ты думаешь, это нечаянно он уехал? – сказал в этот вечер штабный товарищ кавалергардскому офицеру про Ермолова. – Это штуки, это все нарочно. Коновницына подкатить. Посмотри, завтра каша какая будет!

На другой день, рано утром, дряхлый Кутузов встал, помолился богу, оделся и с неприятным сознанием того, что он должен руководить сражением, которого он не одобрял, сел в коляску и выехал из Леташевки, в пяти верстах позади Тарутина, к тому месту, где должны были быть собраны наступающие колонны. Кутузов ехал, засыпая и просыпаясь и прислушиваясь, нет ли справа выстрелов, не начиналось ли дело? Но все еще было тихо. Только начинался рассвет сырого и пасмурного осеннего дня. Подъезжая к Тарутину, Кутузов заметил кавалеристов, ведших на водопой лошадей через дорогу, по которой ехала коляска. Кутузов присмотрелся к ним, остановил коляску и спросил, какого полка? Кавалеристы были из той колонны, которая должна была быть уже далеко впереди в засаде. «Ошибка, может быть», – подумал старый главнокомандующий. Но, проехав еще дальше, Кутузов увидал пехотные полки, ружья в козлах, солдат за кашей и с дровами, в подштанниках. Позвали офицера. Офицер доложил, что никакого приказания о выступлении не было.
– Как не бы… – начал Кутузов, но тотчас же замолчал и приказал позвать к себе старшего офицера. Вылезши из коляски, опустив голову и тяжело дыша, молча ожидая, ходил он взад и вперед. Когда явился потребованный офицер генерального штаба Эйхен, Кутузов побагровел не оттого, что этот офицер был виною ошибки, но оттого, что он был достойный предмет для выражения гнева. И, трясясь, задыхаясь, старый человек, придя в то состояние бешенства, в которое он в состоянии был приходить, когда валялся по земле от гнева, он напустился на Эйхена, угрожая руками, крича и ругаясь площадными словами. Другой подвернувшийся, капитан Брозин, ни в чем не виноватый, потерпел ту же участь.
– Это что за каналья еще? Расстрелять мерзавцев! – хрипло кричал он, махая руками и шатаясь. Он испытывал физическое страдание. Он, главнокомандующий, светлейший, которого все уверяют, что никто никогда не имел в России такой власти, как он, он поставлен в это положение – поднят на смех перед всей армией. «Напрасно так хлопотал молиться об нынешнем дне, напрасно не спал ночь и все обдумывал! – думал он о самом себе. – Когда был мальчишкой офицером, никто бы не смел так надсмеяться надо мной… А теперь!» Он испытывал физическое страдание, как от телесного наказания, и не мог не выражать его гневными и страдальческими криками; но скоро силы его ослабели, и он, оглядываясь, чувствуя, что он много наговорил нехорошего, сел в коляску и молча уехал назад.
Излившийся гнев уже не возвращался более, и Кутузов, слабо мигая глазами, выслушивал оправдания и слова защиты (Ермолов сам не являлся к нему до другого дня) и настояния Бенигсена, Коновницына и Толя о том, чтобы то же неудавшееся движение сделать на другой день. И Кутузов должен был опять согласиться.

На другой день войска с вечера собрались в назначенных местах и ночью выступили. Была осенняя ночь с черно лиловатыми тучами, но без дождя. Земля была влажна, но грязи не было, и войска шли без шума, только слабо слышно было изредка бренчанье артиллерии. Запретили разговаривать громко, курить трубки, высекать огонь; лошадей удерживали от ржания. Таинственность предприятия увеличивала его привлекательность. Люди шли весело. Некоторые колонны остановились, поставили ружья в козлы и улеглись на холодной земле, полагая, что они пришли туда, куда надо было; некоторые (большинство) колонны шли целую ночь и, очевидно, зашли не туда, куда им надо было.
Граф Орлов Денисов с казаками (самый незначительный отряд из всех других) один попал на свое место и в свое время. Отряд этот остановился у крайней опушки леса, на тропинке из деревни Стромиловой в Дмитровское.
Перед зарею задремавшего графа Орлова разбудили. Привели перебежчика из французского лагеря. Это был польский унтер офицер корпуса Понятовского. Унтер офицер этот по польски объяснил, что он перебежал потому, что его обидели по службе, что ему давно бы пора быть офицером, что он храбрее всех и потому бросил их и хочет их наказать. Он говорил, что Мюрат ночует в версте от них и что, ежели ему дадут сто человек конвою, он живьем возьмет его. Граф Орлов Денисов посоветовался с своими товарищами. Предложение было слишком лестно, чтобы отказаться. Все вызывались ехать, все советовали попытаться. После многих споров и соображений генерал майор Греков с двумя казачьими полками решился ехать с унтер офицером.
– Ну помни же, – сказал граф Орлов Денисов унтер офицеру, отпуская его, – в случае ты соврал, я тебя велю повесить, как собаку, а правда – сто червонцев.
Унтер офицер с решительным видом не отвечал на эти слова, сел верхом и поехал с быстро собравшимся Грековым. Они скрылись в лесу. Граф Орлов, пожимаясь от свежести начинавшего брезжить утра, взволнованный тем, что им затеяно на свою ответственность, проводив Грекова, вышел из леса и стал оглядывать неприятельский лагерь, видневшийся теперь обманчиво в свете начинавшегося утра и догоравших костров. Справа от графа Орлова Денисова, по открытому склону, должны были показаться наши колонны. Граф Орлов глядел туда; но несмотря на то, что издалека они были бы заметны, колонн этих не было видно. Во французском лагере, как показалось графу Орлову Денисову, и в особенности по словам его очень зоркого адъютанта, начинали шевелиться.