Definición de consultas: EF Designer

En este tutorial se muestra cómo agregar una consulta de definición y un tipo de entidad correspondiente a un modelo mediante EF Designer. Normalmente, las consultas de definición se usan para proporcionar una funcionalidad similar a la de las vistas de base de datos, pero en este caso la vista se define en el modelo, no en la base de datos. Una consulta de definición permite ejecutar una instrucción SQL especificada en el elemento DefiningQuery de un archivo .edmx. Para más información, vea DefineQuery en la especificación de SSDL.

Al usar la definición de consultas, también debe definir un tipo de entidad en el modelo. El tipo de entidad se usa para mostrar los datos expuestos por la consulta de definición. Tenga en cuenta que los datos mostrados a través de este tipo de entidad son de solo lectura.

Las consultas con parámetros no se pueden ejecutar como consultas de definición. Sin embargo, los datos se pueden actualizar asignando las funciones de inserción, actualización y eliminación del tipo de entidad que los muestra a los procedimientos almacenados. Para más información, vea Insertar, actualizar y eliminar con procedimientos almacenados.

Este tema muestra cómo realizar las siguientes tareas.

  • Agregar una consulta de definición
  • Agregar un tipo de entidad al modelo
  • Asignar la consulta de definición al tipo de entidad

Requisitos previos

Para completar este tutorial, necesitará:

Configuración del proyecto

Este tutorial usa Visual Studio 2012 o versiones posteriores.

  • Abra Visual Studio.
  • En el menú Archivo , elija Nuevoy haga clic en Proyecto.
  • En el panel izquierdo, haga clic en Visual C# y seleccione la plantilla Aplicación de consola.
  • Escriba DefiningQuerySample como nombre del proyecto y haga clic en Aceptar.

 

Creación de un modelo basado en la base de datos School

  • En el Explorador de soluciones, haga clic con el botón derecho en el nombre del proyecto, seleccione Agregar y haga clic en Nuevo elemento.

  • Seleccione Datos en el menú de la izquierda y elija Entity Data Model de ADO.NET en el panel Plantillas.

  • Escriba DefiningQueryModel.edmx como nombre de archivo y, luego, haga clic en Agregar.

  • En el cuadro de diálogo Elegir contenido del modelo, seleccione Generar desde la base de datos y haga clic en Siguiente.

  • Haga clic en Nueva conexión. En el cuadro de diálogo Propiedades de conexión, escriba el nombre del servidor (por ejemplo, (localdb)\mssqllocaldb ), seleccione el método de autenticación, escriba School como nombre de la base de datos y haga clic en Aceptar. El cuadro de diálogo Elegir la conexión de datos se actualiza con la configuración de la conexión de la base de datos.

  • En el cuadro de diálogo Elija los objetos de base de datos, active el nodo Tablas. Esto agregará todas las tablas al modelo School.

  • Haga clic en Finalizar

  • En el Explorador de soluciones, haga clic con el botón derecho en el archivo DefineQueryModel.edmx y seleccione Abrir con….

  • Seleccione Editor XML (texto).

    XML Editor

  • Haga clic en si se le solicita con el mensaje siguiente:

    Warning 2

 

Agregar una consulta de definición

En este paso usaremos el Editor XML para agregar una consulta de definición y un tipo de entidad a la sección SSDL del archivo .edmx. 

  • Agregue un elemento EntitySet a la sección SSDL del archivo .edmx (línea 5 a 13). Especifique lo siguiente:
    • Solo se especifican los atributos Name y EntityType del elemento EntitySet.
    • El nombre completo del tipo de entidad se usa en el atributo EntityType.
    • La instrucción SQL que se va a ejecutar se especifica en el elemento 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" />
  • Agregue el elemento EntityType a la sección SSDL del archivo .edmx como se muestra a continuación. Tenga en cuenta lo siguiente:
    • El valor del atributo Name corresponde al valor del atributo EntityType en el elemento EntitySet anterior, aunque el nombre completo del tipo de entidad se usa en el atributo EntityType.
    • Los nombres de propiedad corresponden a los nombres de columna devueltos por la instrucción SQL en el elemento DefineQuery (anterior).
    • En este ejemplo, la clave de entidad consta de tres propiedades para garantizar un valor de clave único.
    <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>

Nota:

Si más adelante ejecuta el cuadro de diálogo Asistente para la actualización del modelo, se sobrescribirá cualquier cambio realizado en el modelo de almacenamiento, incluida la definición de consultas.

 

Agregar un tipo de entidad al modelo

En este paso agregaremos el tipo de entidad al modelo conceptual mediante EF Designer.  Tener en cuenta lo siguiente:

  • El valor Name de la entidad corresponde al valor del atributo EntityType del elemento EntitySet anterior.
  • Los nombres de propiedad corresponden a los nombres de columna devueltos por la instrucción SQL en el elemento DefineQuery anterior.
  • En este ejemplo, la clave de entidad consta de tres propiedades para garantizar un valor de clave único.

Abra el modelo en EF Designer.

  • Haga doble clic en DefineQueryModel.edmx.

  • Diga al mensaje siguiente:

    Warning 2

 

Todos los objetos seleccionados en el cuadro de diálogo Elegir objetos de base de datos se agregan al modelo.

  • Haga clic con el botón derecho en la superficie de diseño y seleccione Agregar nueva->Entidad....
  • Especifique GradeReport para el nombre de la entidad y CourseID para la propiedad key.
  • Haga clic con el botón derecho en la entidad GradeReport y seleccione Agregar nueva->Propiedad escalar.
  • Cambie el nombre predeterminado de la propiedad a FirstName.
  • Agregue otra propiedad escalar y especifique LastName para el nombre.
  • Agregue otra propiedad escalar y especifique Grade para el nombre.
  • En la ventana Propiedades, cambie la propiedad Type de Grade a Decimal.
  • Seleccione las propiedades FirstName y LastName.
  • En la ventana Propiedades, cambie el valor de la propiedad EntityKey a True.

Como resultado, se agregaron los siguientes elementos a la sección CSDL del archivo .edmx.

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

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

 

Asignar la consulta de definición al tipo de entidad

En este paso, usaremos la ventana Detalles de asignación para asignar los tipos de entidad conceptuales y de almacenamiento.

  • Haga clic con el botón derecho en la entidad GradeReport en la superficie de diseño y seleccione Asignación de tablas.
    Se muestra la ventana Detalles de asignación.
  • Seleccione GradeReport en la lista desplegable <Agregar una tabla o vista> (ubicada en Tablas).
    Aparecen las asignaciones predeterminadas entre el tipo de entidad conceptual y de almacenamiento GradeReport.
    Mapping Details3

Como resultado, el elemento EntitySetMapping se agrega a la sección de asignación del archivo .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>
  • Realice la compilación de la aplicación.

 

Llamar a la consulta de definición en el código

Ahora puede ejecutar la consulta de definición mediante el tipo de entidad GradeReport

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