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

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

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

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

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

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

Необходимые условия

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

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

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

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

 

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

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

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

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

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

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

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

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

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

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

    Редактор XML

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

    Предупреждение 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.

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

    Предупреждение 2

 

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

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

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

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

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

 

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

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

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

В результате элемент 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);
    }