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


Как настроить модель EDM для работы с пользовательскими объектами (платформа Entity Framework)

Если с моделью Entity Data Model EDM нужно использовать пользовательские классы данных, типы сущностей и свойства, определенные в файле на языке CSDL, должны соответствовать пользовательским классам данных. Средства платформы Entity Framework создают набор файлов сопоставления, в которых типы сущности и наборы сущностей в файле на языке CSDL сопоставляются таблицам в базе данных. Процесс обновления этих файлов сопоставления в целях соответствия пользовательским классам данных выглядит следующим образом.

  1. Обновление CSDL-файла для его соответствия пользовательским классам данных.

  2. Обновление сопоставлений на языке MSL.

  3. Обновление файла на языке SSDL (при необходимости).

  4. Проверка обновленных файлов сопоставления.

  5. Запрет создания уровня объектов в среде Visual Studio.

Для запуска примера, приведенного в этом разделе, необходимо сначала при помощи программы Генератор модели EDM (EdmGen.exe) или мастера Мастер моделей EDM создать файлы сопоставления модели EDM. Дополнительные сведения см. в разделе Как использовать программу EdmGen.exe для формирования модели EDM (Entity Framework). Если используется конструктор моделей EDM в среде Visual Studio, то необходимо также отключить создание уровня объектов на основе обновленного CSDL-файла. В противном случае в проекте появятся повторяющиеся классы данных.

Обновление файла на языке CSDL для соответствия пользовательским объектам данных

  1. Откройте файл на языке CSDL в среде Visual Studio или «Блокноте».

  2. Переименуйте элементы EntityType и EntitySet, чтобы их имена соответствовали именам пользовательских классов данных.

  3. Удалите элементы EntityType и EntitySet всех сущностей, не имеющих соответствий в пользовательских классах данных.

  4. Переименуйте элементы Property всех типов, чтобы их имена соответствовали именам свойств в пользовательских классах данных.

  5. Удалите элементы Property всех свойств, не существующих в пользовательских классах данных.

  6. Сохраните изменения в CSDL-файле.

Обновление MSL-файла для сопоставления пользовательских объектов данных с объектами в источнике данных

  1. Откройте файл на языке MSL в среде Visual Studio или «Блокноте».

  2. Переименуйте элемент EntitySetMapping и атрибут TypeName, чтобы их имена соответствовали именам пользовательских классов.

  3. Удалите элементы EntitySetMapping для всех сущностей, не имеющих соответствий в пользовательских классах данных.

  4. Переименуйте элементы ScalarProperty всех типов, чтобы их имена соответствовали именам свойств в пользовательских классах данных.

  5. Удалите элемент ScalarProperty для всех свойств, не существующих в пользовательских классах данных.

  6. Переименуйте элемент EndProperty в AssociationSetMapping, чтобы его имя соответствовало именам пользовательских классов.

  7. Переименуйте элементы ScalarProperty во всех сущностях AssociationSetMapping, чтобы их имена соответствовали именам свойств в пользовательских классах данных.

    NoteПримечание.

    Не изменяйте свойства ColumnName.

  8. Удалите элемент AssociationSetMapping для всех ассоциаций между сущностями, не существующими в пользовательских классах данных.

  9. Сохраните изменения в MSL-файле.

Обновление SSDL-файла для удаления сущностей, не существующих в пользовательских классах данных

  1. Откройте файл на языке SSDL в среде Visual Studio или «Блокноте».

  2. Удалите элементы EntityType для всех сущностей, не сопоставленных пользовательским классам данных.

  3. Удалите элементы ScalarProperty для всех сущностей, не сопоставленных свойствам в пользовательских классах данных.

  4. Сохраните изменения в SSDL-файле.

Проверка обновленных файлов сопоставления

  1. Запустите программу EdmGen.exe в каталоге, содержащем файлы сопоставления. Используйте следующую команду:

    %windir%\Microsoft.NET\Framework\v3.5\edmgen.exe /mode:ValidateArtifacts  
    /inssdl:.\YourModel.ssdl /inmsl:.\YourModel.msl /incsdl:.\YourModel.csdl 
    
    NoteПримечание.

    Удалите все переводы строки и замените YourModel именем, используемым в файле сопоставления.

  2. Просмотрите выходные данные и устраните ошибки проверки.

Повторное формирование, сохранение и удаление автоматически сформированного объектного кода

  1. В Обозревателе решений среды Visual Studio щелкните правой кнопкой мыши файл CSDL** и выберите команду Пользовательское средство.

    Будет повторно создан уровень объектов на основе измененного CSDL-файла.

  2. Разверните узел CSDL-файла, откройте его в конструкторе и сохраните под другим именем.

    Сохранится файл автоматически сформированного уровня объектов. Код этого файла используется в разделе Как использовать службы объектов с пользовательскими объектами (платформа Entity Framework).

  3. Исключите из проекта файл конструктора.

  4. Выберите CSDL-файл и очистите значение «Пользовательское средство» в окне Свойства.

    В результате запрещается повторное создание файла уровня объектов. Чтобы создать этот файл в будущем, введите EntityModelCodeGenerator в поле «Пользовательское средство» в окне Свойства и повторите шаг 1.

Примеры

Следующий файл CSDL настроен для поддержки пользовательских классов данных Orders и LineItem.

<Schema Namespace="Microsoft.Samples.Edm" Alias="Self" xmlns="https://schemas.microsoft.com/ado/2006/04/edm">
  <EntityContainer Name="SalesOrdersEntities">
    <EntitySet Name="LineItem" EntityType="Microsoft.Samples.Edm.LineItem" />
    <EntitySet Name="Order" EntityType="Microsoft.Samples.Edm.Order" />
    <AssociationSet Name="FK_LineItem_Order_OrderId" Association="Microsoft.Samples.Edm.FK_LineItem_Order_OrderId">
      <End Role="Order" EntitySet="Order" />
      <End Role="LineItem" EntitySet="LineItem" />
    </AssociationSet>
  </EntityContainer>
  <EntityType Name="LineItem">
    <Key>
      <PropertyRef Name="LineItemId" />
    </Key>
    <Property Name="LineItemId" Type="Int32" Nullable="false" />
    <Property Name="TrackingNumber" Type="String" MaxLength="25" />
    <Property Name="Quantity" Type="Int16" Nullable="false" />
    <Property Name="Product" Type="Int32" Nullable="false" />
    <Property Name="Price" Type="Decimal" Nullable="false" Precision="19" Scale="4" />
    <Property Name="Discount" Type="Decimal" Nullable="false" Precision="19" Scale="4" />
    <NavigationProperty Name="Order" Relationship="Microsoft.Samples.Edm.FK_LineItem_Order_OrderId" 
                        FromRole="LineItem" ToRole="Order" />
  </EntityType>
  <EntityType Name="Order">
    <Key>
      <PropertyRef Name="OrderId" />
    </Key>
    <Property Name="OrderId" Type="Int32" Nullable="false" />
    <Property Name="OrderDate" Type="DateTime" Nullable="false" />
    <Property Name="DueDate" Type="DateTime" Nullable="false" />
    <Property Name="ShipDate" Type="DateTime" />
    <Property Name="Status" Type="Byte" Nullable="false" />
    <Property Name="Customer" Type="Int32" Nullable="false" />
    <Property Name="SubTotal" Type="Decimal" Nullable="false" Precision="19" Scale="4" />
    <Property Name="TaxAmt" Type="Decimal" Nullable="false" Precision="19" Scale="4" />
    <Property Name="Freight" Type="Decimal" Nullable="false" Precision="19" Scale="4" />
    <Property Name="ExtendedInfo" Type="Self.OrderInfo" Nullable="false" />
    <NavigationProperty Name="LineItem" Relationship="Microsoft.Samples.Edm.FK_LineItem_Order_OrderId" 
                        FromRole="Order" ToRole="LineItem" />
  </EntityType>
    <ComplexType Name="OrderInfo">
        <Property Name="OrderNumber" Type="String" Nullable="false" MaxLength="25" />
        <Property Name="PurchaseOrder" Type="String" MaxLength="25" />
        <Property Name="AccountNumber" Type="String" MaxLength="15" />
        <Property Name="Comment" Type="String" MaxLength="128" />
    </ComplexType>
  <Association Name="FK_LineItem_Order_OrderId">
    <End Role="Order" Type="Microsoft.Samples.Edm.Order" Multiplicity="1" />
    <End Role="LineItem" Type="Microsoft.Samples.Edm.LineItem" Multiplicity="*" />
  </Association>
</Schema>

Следующий MSL-файл настроен для сопоставления пользовательских классов данных Orders и LineItem таблицам SalesOrderHeader и SalesOrderDetail в базе данных AdventureWorks.

<Mapping Space="C-S" xmlns="urn:schemas-microsoft-com:windows:storage:mapping:CS">
  <EntityContainerMapping StorageEntityContainer="Sales" CdmEntityContainer="SalesOrdersEntities">
    <EntitySetMapping Name="LineItem" StoreEntitySet="SalesOrderDetail" TypeName="Microsoft.Samples.Edm.LineItem">
      <ScalarProperty Name="LineItemId" ColumnName="SalesOrderDetailID" />
      <ScalarProperty Name="TrackingNumber" ColumnName="CarrierTrackingNumber" />
      <ScalarProperty Name="Quantity" ColumnName="OrderQty" />
      <ScalarProperty Name="Product" ColumnName="ProductID" />
      <ScalarProperty Name="Price" ColumnName="UnitPrice" />
      <ScalarProperty Name="Discount" ColumnName="UnitPriceDiscount" />
    </EntitySetMapping>
    <EntitySetMapping Name="Order" StoreEntitySet="SalesOrderHeader" TypeName="Microsoft.Samples.Edm.Order">
      <ScalarProperty Name="OrderId" ColumnName="SalesOrderID" />
      <ScalarProperty Name="OrderDate" ColumnName="OrderDate" />
      <ScalarProperty Name="DueDate" ColumnName="DueDate" />
      <ScalarProperty Name="ShipDate" ColumnName="ShipDate" />
      <ScalarProperty Name="Status" ColumnName="Status" />
      <ScalarProperty Name="Customer" ColumnName="CustomerID" />
      <ScalarProperty Name="SubTotal" ColumnName="SubTotal" />
      <ScalarProperty Name="TaxAmt" ColumnName="TaxAmt" />
      <ScalarProperty Name="Freight" ColumnName="Freight" />
      <ComplexProperty Name ="ExtendedInfo" TypeName ="Microsoft.Samples.Edm.OrderInfo">
        <ScalarProperty Name="OrderNumber" ColumnName="SalesOrderNumber" />
        <ScalarProperty Name="PurchaseOrder" ColumnName="PurchaseOrderNumber" />
        <ScalarProperty Name="AccountNumber" ColumnName="AccountNumber" />
        <ScalarProperty Name="Comment" ColumnName="Comment" />
      </ComplexProperty>
    </EntitySetMapping>
    <AssociationSetMapping Name="FK_LineItem_Order_OrderId" TypeName="Microsoft.Samples.Edm.FK_LineItem_Order_OrderId" StoreEntitySet="SalesOrderDetail">
      <EndProperty Name="Order">
        <ScalarProperty Name="OrderId" ColumnName="SalesOrderID" />
      </EndProperty>
      <EndProperty Name="LineItem">
        <ScalarProperty Name="LineItemId" ColumnName="SalesOrderDetailID" />
      </EndProperty>
      <Condition ColumnName="SalesOrderID" IsNull="false" />
    </AssociationSetMapping>
  </EntityContainerMapping>
</Mapping>

Следующий файл SSDL настроен для поддержки пользовательских классов данных Orders и LineItem с помощью таблиц SalesOrderHeader и SalesOrderDetail в базе данных AdventureWorks.

<Schema Namespace="Microsoft.Samples.Edm.Store" Alias="Self" Provider="System.Data.SqlClient" ProviderManifestToken="2005" xmlns="https://schemas.microsoft.com/ado/2006/04/edm/ssdl">
  <EntityContainer Name="Sales">
    <EntitySet Name="SalesOrderDetail" EntityType="Microsoft.Samples.Edm.Store.SalesOrderDetail" />
    <EntitySet Name="SalesOrderHeader" EntityType="Microsoft.Samples.Edm.Store.SalesOrderHeader" />
    <AssociationSet Name="FK_LineItem_Orders_OrderId" Association="Microsoft.Samples.Edm.Store.FK_SalesOrderDetail_SalesOrderHeader_SalesOrderID">
      <End Role="SalesOrderHeader" EntitySet="SalesOrderHeader" />
      <End Role="SalesOrderDetail" EntitySet="SalesOrderDetail" />
    </AssociationSet>
  </EntityContainer>
  <EntityType Name="SalesOrderDetail">
    <Key>
      <PropertyRef Name="SalesOrderDetailID" />
    </Key>
    <Property Name="SalesOrderID" Type="int" Nullable="false" />
    <Property Name="SalesOrderDetailID" Type="int" Nullable="false" StoreGeneratedPattern="Identity" />
    <Property Name="CarrierTrackingNumber" Type="nvarchar" MaxLength="25" />
    <Property Name="OrderQty" Type="smallint" Nullable="false" />
    <Property Name="ProductID" Type="int" Nullable="false" />
    <Property Name="UnitPrice" Type="money" Nullable="false" />
    <Property Name="UnitPriceDiscount" Type="money" Nullable="false" />
  </EntityType>
  <EntityType Name="SalesOrderHeader">
    <Key>
      <PropertyRef Name="SalesOrderID" />
    </Key>
    <Property Name="SalesOrderID" Type="int" Nullable="false" StoreGeneratedPattern="Identity" />
    <Property Name="OrderDate" Type="datetime" Nullable="false" />
    <Property Name="DueDate" Type="datetime" Nullable="false" />
    <Property Name="ShipDate" Type="datetime" />
    <Property Name="Status" Type="tinyint" Nullable="false" />
    <Property Name="SalesOrderNumber" Type="nvarchar" Nullable="false" StoreGeneratedPattern="Computed" MaxLength="25" />
    <Property Name="PurchaseOrderNumber" Type="nvarchar" MaxLength="25" />
    <Property Name="AccountNumber" Type="nvarchar" MaxLength="15" />
    <Property Name="CustomerID" Type="int" Nullable="false" />
    <Property Name="SubTotal" Type="money" Nullable="false" />
    <Property Name="TaxAmt" Type="money" Nullable="false" />
    <Property Name="Freight" Type="money" Nullable="false" />
    <Property Name="Comment" Type="nvarchar" MaxLength="128" />
  </EntityType>
  <Association Name="FK_SalesOrderDetail_SalesOrderHeader_SalesOrderID">
    <End Role="SalesOrderHeader" Type="Microsoft.Samples.Edm.Store.SalesOrderHeader" Multiplicity="1" />
    <End Role="SalesOrderDetail" Type="Microsoft.Samples.Edm.Store.SalesOrderDetail" Multiplicity="*" />
    <ReferentialConstraint>
      <Principal Role="SalesOrderHeader">
        <PropertyRef Name="SalesOrderID" />
      </Principal>
      <Dependent Role="SalesOrderDetail">
        <PropertyRef Name="SalesOrderID" />
      </Dependent>
    </ReferentialConstraint>
  </Association>
</Schema>

См. также

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

Настройка объектов (платформа Entity Framework)

Другие ресурсы

Спецификация схем и сопоставлений (платформа Entity Framework)
Работа с пользовательскими объектами (задачи Entity Framework)