Поделиться через


Спецификация манифеста поставщика

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

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

Типы, поддерживаемые поставщиком, явно или неявно поддерживаются базовой базой данных. Эти типы необязательно совпадают с типами хранилища, но используются поставщиком для поддержки Entity Framework . Типы поставщика и хранилища описываются в терминах модели EDM.

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

Требования

Платформа Entity Framework и хранилище данных должны иметь возможность обмениваться данными известных типов, исключая потерю и усечение данных.

Манифест поставщика должен загружаться средствами во время разработки без необходимости установления соединения с хранилищем данных.

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

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

В следующей таблице описываются виды исключений, вызываемые Entity Framework , когда при взаимодействии с поставщиком создаются исключения.

Проблема Исключение

Поставщик не поддерживает GetProviderManifest в DbProviderServices.

ProviderIncompatibleException

Отсутствует манифест поставщика: поставщик возвращает значение null при попытке получить манифест поставщика.

ProviderIncompatibleException

Недопустимый манифест поставщика: поставщик возвращает недопустимый XML-код при попытке получить манифест поставщика.

ProviderIncompatibleException

Сценарии

Поставщик должен поддерживать следующие сценарии:

Разработка поставщика с симметричным сопоставлением типов

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

В случае простой структуры домена можно создать статический манифест поставщика в декларативном стиле.

Создайте XML-файл с двумя разделами.

  • Список типов поставщика в терминах эквивалентов EDM для типа или функции хранилища. Для типов хранилища имеются эквиваленты в модели EDM. Для функций хранилища имеются соответствующие функции в модели EDM. Например, тип varchar является типом SQL Server, а в модели EDM ему соответствует тип string.

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

Разработка поставщика с асимметричным сопоставлением типов

При создании поставщика хранилища данных для Entity Framework сопоставление типов между моделью EDM и поставщиком для некоторых типов может отличаться от обратного сопоставления. Например, непривязанный тип EDM PrimitiveTypeKind.String может сопоставляться с типом nvarchar(4000) в поставщике, а тип nvarchar(4000) сопоставляется с типом EDM PrimitiveTypeKind.String(MaxLength=4000).

Создайте XML-файл с двумя разделами.

  • Список типов поставщика в терминах модели EDM и определение сопоставления в обоих направлениях: от модели EDM к поставщику и наоборот.

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

Возможность обнаружения манифеста поставщика

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

dfb3d02b-7a8c-4d51-ac5a-a73d8aa145e6

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

Маркер манифеста поставщика

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

Пример.

<Schema Namespace="Northwind" Provider="System.Data.SqlClient" ProviderManifestToken="2005" xmlns:edm="https://schemas.microsoft.com/ado/2006/04/edm/ssdl" xmlns="https://schemas.microsoft.com/ado/2006/04/edm/ssdl">

Модель программирования манифеста поставщика

Поставщики являются производными от класса DbXmlEnabledProviderManifest и поэтому могут указывать манифесты декларативно. На следующем рисунке показана иерархия классов поставщика.

None

API обнаружения

Манифест поставщика загружается загрузчиком метаданных хранилища (StoreItemCollection) с помощью соединения с хранилищем данных или маркера манифеста поставщика.

Использование соединения с хранилищем данных

Если доступно соединение с хранилищем данных, вызовите метод DbProvderServices.GetProviderManifestToken, чтобы возвратить маркер, переданный в метод GetProviderManifest, который возвращает DbProviderManifest. Этот метод служит делегатом для реализации GetDbProviderManifestToken в поставщике.

public string GetProviderManifestToken(DbConnection connection);
public DbProviderManifest GetProviderManifest(string manifestToken);

Использование маркера манифеста поставщика

В случае автономной работы маркер берется из представления SSDL. Язык SSDL позволяет указывать ProviderManifestToken (дополнительные сведения см. в разделе Элемент Schema (SSDL)). Например, если не удается открыть соединение, то в SSDL используется маркер манифеста поставщика, в котором указываются сведения о манифесте.

public DbProviderManifest GetProviderManifest(string manifestToken);

Схема манифеста поставщика

Схема данных, определенных для каждого поставщика, содержит статические данные для обработки в метаданных.

<?xml version="1.0" encoding="utf-8"?>
<xs:schema elementFormDefault="qualified"
   xmlns:xs="http://www.w3.org/2001/XMLSchema"
   targetNamespace="https://schemas.microsoft.com/ado/2006/04/edm/providermanifest"
   xmlns:pm="https://schemas.microsoft.com/ado/2006/04/edm/providermanifest">

  <xs:element name="ProviderManifest">
    <xs:complexType>
      <xs:sequence>
        <xs:element name="Types" type="pm:TTypes" minOccurs="1" maxOccurs="1" />
        <xs:element name="Functions" type="pm:TFunctions" minOccurs="0" maxOccurs="1"/>
      </xs:sequence>
      <xs:attribute name="Namespace" type="xs:string" use="required"/>
    </xs:complexType>
  </xs:element>
  <xs:complexType name="TVersion">
    <xs:attribute name="Major" type="xs:int" use="required" />
    <xs:attribute name="Minor" type="xs:int" use="required" />
    <xs:attribute name="Build" type="xs:int" use="required" />
    <xs:attribute name="Revision" type="xs:int" use="required" />
  </xs:complexType>

  <xs:complexType name="TIntegerFacetDescription">
    <xs:attribute name="Minimum" type="xs:int" use="optional" />
    <xs:attribute name="Maximum" type="xs:int" use="optional" />
    <xs:attribute name="DefaultValue" type="xs:int" use="optional" />
    <xs:attribute name="Constant" type="xs:boolean" default="false" />
  </xs:complexType>

  <xs:complexType name="TBooleanFacetDescription">
    <xs:attribute name="DefaultValue" type="xs:boolean" use="optional" />
    <xs:attribute name="Constant" type="xs:boolean" default="true" />
  </xs:complexType>

  <xs:complexType name="TDateTimeFacetDescription">
    <xs:attribute name="Constant" type="xs:boolean" default="false" />
  </xs:complexType>

  <xs:complexType name="TFacetDescriptions">
    <xs:choice maxOccurs="unbounded">
      <xs:element name="Precision" minOccurs="0" maxOccurs="1" type="pm:TIntegerFacetDescription"/>
      <xs:element name="Scale" minOccurs="0" maxOccurs="1" type="pm:TIntegerFacetDescription"/>
      <xs:element name="MaxLength" minOccurs="0" maxOccurs="1" type="pm:TIntegerFacetDescription"/>
      <xs:element name="Unicode" minOccurs="0" maxOccurs="1" type="pm:TBooleanFacetDescription"/>
      <xs:element name="FixedLength" minOccurs="0" maxOccurs="1" type="pm:TBooleanFacetDescription"/>
    </xs:choice>
  </xs:complexType>

  <xs:complexType name="TType">
    <xs:sequence>
      <xs:element name="FacetDescriptions" type="pm:TFacetDescriptions" minOccurs="0" maxOccurs="1"/>
    </xs:sequence>
    <xs:attribute name="Name" type="xs:string" use="required"/>
    <xs:attribute name="PrimitiveTypeKind" type="pm:TPrimitiveTypeKind" use="required" />
  </xs:complexType>

  <xs:complexType name="TTypes">
    <xs:sequence>
      <xs:element name="Type" type="pm:TType" minOccurs="0" maxOccurs="unbounded"/>
    </xs:sequence>
  </xs:complexType>

  <xs:attributeGroup name="TFacetAttribute">
    <xs:attribute name="Precision" type="xs:int" use="optional"/>
    <xs:attribute name="Scale" type="xs:int" use="optional"/>
    <xs:attribute name="MaxLength" type="xs:int" use="optional"/>
    <xs:attribute name="Unicode" type="xs:boolean" use="optional"/>
    <xs:attribute name="FixedLength" type="xs:boolean" use="optional"/>
  </xs:attributeGroup>

  <xs:complexType name="TFunctionParameter">
    <xs:attribute name="Name" type="xs:string" use="required" />
    <xs:attribute name="Type" type="xs:string" use="required" />
    <xs:attributeGroup ref="pm:TFacetAttribute" />
    <xs:attribute name="Mode" type="pm:TParameterDirection" use="required" />
  </xs:complexType>

  <xs:complexType name="TReturnType">
    <xs:attribute name="Type" type="xs:string" use="required" />
    <xs:attributeGroup ref="pm:TFacetAttribute" />
  </xs:complexType>

  <xs:complexType name="TFunction">
    <xs:choice minOccurs="0" maxOccurs ="unbounded">
      <xs:element name ="ReturnType" type="pm:TReturnType" minOccurs="0" maxOccurs="1" />
      <xs:element name="Parameter" type="pm:TFunctionParameter" minOccurs="0" maxOccurs="unbounded"/>
    </xs:choice>
    <xs:attribute name="Name" type="xs:string" use="required" />
    <xs:attribute name="Aggregate" type="xs:boolean" use="optional" />
    <xs:attribute name="BuiltIn" type="xs:boolean" use="optional" />
    <xs:attribute name="StoreFunctionName" type="xs:string" use="optional" />
    <xs:attribute name="NiladicFunction" type="xs:boolean" use="optional" />
    <xs:attribute name="ParameterTypeSemantics" type="pm:TParameterTypeSemantics" use="optional" default="AllowImplicitConversion" />
  </xs:complexType>

  <xs:complexType name="TFunctions">
    <xs:sequence>
      <xs:element name="Function" type="pm:TFunction" minOccurs="0" maxOccurs="unbounded"/>
    </xs:sequence>
  </xs:complexType>

  <xs:simpleType name="TPrimitiveTypeKind">
    <xs:restriction base="xs:string">
      <xs:enumeration value="Binary"/>
      <xs:enumeration value="Boolean"/>
      <xs:enumeration value="Byte"/>
      <xs:enumeration value="Decimal"/>
      <xs:enumeration value="DateTime"/>
      <xs:enumeration value="Time"/>
      <xs:enumeration value="DateTimeOffset"/>        
      <xs:enumeration value="Double"/>
      <xs:enumeration value="Guid"/>
      <xs:enumeration value="Single"/>
      <xs:enumeration value="SByte"/>
      <xs:enumeration value="Int16"/>
      <xs:enumeration value="Int32"/>
      <xs:enumeration value="Int64"/>
      <xs:enumeration value="String"/>
    </xs:restriction>
  </xs:simpleType>


  <xs:simpleType name="TParameterDirection">
    <xs:restriction base="xs:string">
      <xs:enumeration value="In"/>
      <xs:enumeration value="Out"/>
      <xs:enumeration value="InOut"/>
    </xs:restriction>
  </xs:simpleType>

  <xs:simpleType name="TParameterTypeSemantics">
    <xs:restriction base="xs:string">
      <xs:enumeration value="ExactMatchOnly" />
      <xs:enumeration value="AllowImplicitPromotion" />
      <xs:enumeration value="AllowImplicitConversion" />
    </xs:restriction>
  </xs:simpleType>
</xs:schema>

Узел типов

Узел типов в манифесте поставщика содержит сведения о типах, которые поддерживаются хранилищем данных непосредственно или с помощью поставщика.

Узел типа

В каждом узле типа определяется тип поставщика в терминах модели EDM. В узле типа описывается имя типа поставщика и сведения, связанные с типом модели, который сопоставляется с типом поставщика, и с аспектами, описывающими это сопоставление.

Для выражения этих сведений о типе в манифесте поставщика каждое определение TypeInformation должно определять несколько аспектов для каждого типа.

Имя атрибута Тип данных Обязательный Значение по умолчанию Описание

Name

String

Да

не применяется

Имя типа данных, зависящего от поставщика

PrimitiveTypeKind

PrimitiveTypeKind

Да

не применяется

Имя типа в модели EDM

Узел функции

В каждом узле функции определяется функция, доступная посредством поставщика.

Имя атрибута Тип данных Обязательный Значение по умолчанию Описание

Name

String

Да

не применяется

Идентификатор или имя функции

ReturnType

String

Нет

Void

Тип возвращаемого значения функции в модели EDM

Aggregate

Boolean

Нет

False

Значение True, если функция является агрегатной

BuiltIn

Boolean

Нет

True

Значение True, если функция встроена в хранилище данных

StoreFunctionName

String

Нет

<Name>

Имя функции в хранилище данных. Реализует уровень перенаправления для имен функций.

NiladicFunction

Boolean

Нет

False

Значение True, если функция не требует параметров и вызывается без параметров

ParameterType

Semantics

ParameterSemantics

Нет

AllowImplicit

Conversion

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

  • ExactMatchOnly

  • AllowImplicitPromotion

  • AllowImplicitConversion

Узел параметров

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

Имя атрибута Тип данных Обязательный Значение по умолчанию Описание

Name

String

Да

не применяется

Идентификатор или имя параметра.

Type

String

Да

не применяется

Тип параметра в модели EDM.

Mode

Parameter

Direction

Да

не применяется

Направление параметра:

  • in

  • out

  • inout

Атрибут Namespace

В каждом поставщике хранилища данных должно определяться пространство имен или группа пространств имен для сведений, определяемых в манифесте. Это пространство имен можно использовать в запросах Entity SQL для разрешения имен функций и типов. Пример: SqlServer. Это пространство имен должно отличаться от канонического пространства имен EDM, определенного в службах сущностей для стандартных функций, поддерживаемых запросами Entity SQL.

См. также

Основные понятия

Создание поставщика данных Entity Framework