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


Определение запроса — конструктор EF

В этом пошаговом руководстве показано, как добавить определяющий запрос и соответствующий тип сущности в модель с помощью ef Designer. Определяющий запрос обычно используется для предоставления функций, аналогичных функциям, предоставляемым представлением базы данных, но представление определяется в модели, а не в базе данных. Определяющий запрос позволяет выполнить инструкцию SQL, указанную в элементе DefiningQuery файла edmx. Дополнительные сведения см. в разделе "ОпределениеQuery" в спецификации SSDL.

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

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

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

  • Добавление определяющего запроса
  • Добавление типа сущности в модель
  • Сопоставление определяемого запроса с типом сущности

Необходимые компоненты

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

  • Последняя версия Visual Studio.
  • Пример базы данных учебного заведения.

Настройка проекта

В этом пошаговом руководстве используется Visual Studio 2012 или более поздней версии.

  • Откройте Visual Studio.
  • В меню Файл укажите Создать, затем нажмите Проект.
  • В левой области щелкните Visual C#, а затем выберите шаблон консольного приложения .
  • Введите ОпределениеQuerySample в качестве имени проекта и нажмите кнопку "ОК".

 

Создание модели на основе учебной базы данных

  • Щелкните правой кнопкой мыши имя проекта в Обозреватель решений, выберите пункт "Добавить" и выберите пункт "Создать элемент".

  • Выберите данные из меню слева и выберите ADO.NET модель данных сущности в области шаблонов.

  • Введите DefiningQueryModel.edmx для имени файла и нажмите кнопку "Добавить".

  • В диалоговом окне "Выбор содержимого модели" выберите "Создать из базы данных" и нажмите кнопку "Далее".

  • Нажмите кнопку "Создать Подключение". В диалоговом окне "Свойства Подключение ion" введите имя сервера (например, (localdb)\mssqllocaldb), выберите метод проверки подлинности, введите School для имени базы данных и нажмите кнопку "ОК". Диалоговое окно выбора данных Подключение ion обновляется с параметром подключения к базе данных.

  • В диалоговом окне "Выбор объектов базы данных" проверка узле "Таблицы". Это добавит все таблицы в модель School .

  • Нажмите кнопку Готово.

  • В Обозреватель решений щелкните правой кнопкой мыши файл DefiningQueryModel.edmx и выберите "Открыть с...".

  • Выберите редактор XML (текст).

    XML Editor

  • Нажмите кнопку "Да", если появится следующее сообщение:

    Warning 2

 

Добавление определяющего запроса

На этом шаге мы будем использовать редактор XML для добавления определяющего запроса и типа сущности в раздел SSDL файла edmx. 

  • Добавьте элемент EntitySet в раздел SSDL файла edmx (строка 5 от 13). Укажите следующее:
    • Указаны только атрибуты Name и EntityType элемента EntitySet.
    • Полное имя типа сущности используется в атрибуте EntityType .
    • Инструкция SQL, выполняемая, указана в элементе DefiningQuery .
    <!-- SSDL content -->
    <edmx:StorageModels>
      <Schema Namespace="SchoolModel.Store" Alias="Self" Provider="System.Data.SqlClient" ProviderManifestToken="2008" xmlns:store="http://schemas.microsoft.com/ado/2007/12/edm/EntityStoreSchemaGenerator" xmlns="http://schemas.microsoft.com/ado/2009/11/edm/ssdl">
        <EntityContainer Name="SchoolModelStoreContainer">
           <EntitySet Name="GradeReport" EntityType="SchoolModel.Store.GradeReport">
              <DefiningQuery>
                SELECT CourseID, Grade, FirstName, LastName
                FROM StudentGrade
                JOIN
                (SELECT * FROM Person WHERE EnrollmentDate IS NOT NULL) AS p
                ON StudentID = p.PersonID
              </DefiningQuery>
          </EntitySet>
          <EntitySet Name="Course" EntityType="SchoolModel.Store.Course" store:Type="Tables" Schema="dbo" />
  • Добавьте элемент EntityType в раздел SSDL в edmx. файл, как показано ниже. Обратите внимание на следующее:
    • Значение атрибута Name соответствует значению атрибута EntityType в элементе EntitySet выше, хотя полное имя типа сущности используется в атрибуте EntityType.
    • Имена свойств соответствуют именам столбцов, возвращаемым инструкцией SQL в элементе DefiningQuery (выше).
    • В данном примере ключ сущности состоит из трех свойств, что обеспечивает уникальность значения ключа.
    <EntityType Name="GradeReport">
      <Key>
        <PropertyRef Name="CourseID" />
        <PropertyRef Name="FirstName" />
        <PropertyRef Name="LastName" />
      </Key>
      <Property Name="CourseID"
                Type="int"
                Nullable="false" />
      <Property Name="Grade"
                Type="decimal"
                Precision="3"
                Scale="2" />
      <Property Name="FirstName"
                Type="nvarchar"
                Nullable="false"
                MaxLength="50" />
      <Property Name="LastName"
                Type="nvarchar"
                Nullable="false"
                MaxLength="50" />
    </EntityType>

Примечание.

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

 

Добавление типа сущности в модель

На этом шаге мы добавим тип сущности в концептуальную модель с помощью конструктора EF.  Обратите внимание на следующее:

  • Имя сущности соответствует значению атрибута EntityType в элементе EntitySet выше.
  • Имена свойств соответствуют именам столбцов, возвращаемым инструкцией SQL в элементе DefiningQuery выше.
  • В данном примере ключ сущности состоит из трех свойств, что обеспечивает уникальность значения ключа.

Откройте модель в конструкторе EF.

  • Дважды щелкните элемент DefiningQueryModel.edmx.

  • Скажите "Да " в следующем сообщении:

    Warning 2

 

Отображается конструктор сущностей, предоставляющий область конструктора для редактирования модели.

  • Щелкните правой кнопкой мыши область конструктора и выберите "Добавить новую> сущность...".
  • Укажите GradeReport для имени сущности и CourseID для свойства ключа.
  • Щелкните правой кнопкой мыши сущность GradeReport и выберите "Добавить новое скалярное> свойство".
  • Измените имя свойства по умолчанию на FirstName.
  • Добавьте другое скалярное свойство и укажите LastName для имени.
  • Добавьте другое скалярное свойство и укажите класс для имени.
  • В окне "Свойства" измените свойство Type класса на Десятичное.
  • Выберите свойства FirstName и LastName.
  • В окне свойств измените значение свойства EntityKey на True.

В результате в раздел CSDL файла edmx были добавлены следующие элементы.

    <EntitySet Name="GradeReport" EntityType="SchoolModel.GradeReport" />

    <EntityType Name="GradeReport">
    . . .
    </EntityType>

 

Сопоставление определяемого запроса с типом сущности

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

  • Щелкните правой кнопкой мыши сущность GradeReport в области конструктора и выберите "Сопоставление таблиц".
    Откроется окно сведений о сопоставлении.
  • Выберите GradeReport из <раскрывающегося списка "Добавить таблицу или представление> " (расположенную в разделе "Таблицы").
    По умолчанию отображаются сопоставления между типом сущности "Концептуальный" и "Класс хранилища".
    Mapping Details3

В результате элемент EntitySetMapping добавляется в раздел сопоставления файла edmx. 

    <EntitySetMapping Name="GradeReports">
      <EntityTypeMapping TypeName="IsTypeOf(SchoolModel.GradeReport)">
        <MappingFragment StoreEntitySet="GradeReport">
          <ScalarProperty Name="LastName" ColumnName="LastName" />
          <ScalarProperty Name="FirstName" ColumnName="FirstName" />
          <ScalarProperty Name="Grade" ColumnName="Grade" />
          <ScalarProperty Name="CourseID" ColumnName="CourseID" />
        </MappingFragment>
      </EntityTypeMapping>
    </EntitySetMapping>
  • Скомпилируйте приложение.

 

Вызов определения запроса в коде

Теперь можно выполнить определяющий запрос с помощью типа сущности GradeReport

    using (var context = new SchoolEntities())
    {
        var report = context.GradeReports.FirstOrDefault();
        Console.WriteLine("{0} {1} got {2}",
            report.FirstName, report.LastName, report.Grade);
    }