¿Qué es LINQ para Delphi en EntityDAC?

La idea básica de EntityDAC, como cualquier ORM para RAD Studio, es liberar al programador de la necesidad de implementar la lógica comercial y la lógica de interacción de la base de datos por separado en el código fuente de la aplicación. Al escribir código, el programador se abstrae de los detalles de la base de datos y administra los objetos de la base de datos, utilizando las estructuras de su lenguaje de programación "nativo".

Es decir, si el enfoque clásico para actualizar un registro de base de datos usa un código similar:

Query1.SQL.Text := 'UPDATE Master ' +
                   'SET Name=""New Name'' ' +
                   'WHERE MasterId = 10';
Query1.Execute;

luego, al usar EntityDAC, se realiza una operación similar de una manera más "natural":

var
  Master: TMaster;
begin
  // retrieve a TMaster instance
  
  Master.Name := 'New Name';
  Master.Save;
end;

En el ejemplo anterior, el fragmento de código se comenta intencionalmente, lo que lógicamente nos lleva a la siguiente tarea: obtener una entidad (o colección de objetos) de acuerdo con los criterios necesarios en el contexto de la ideología ORM.

El enfoque clásico utiliza SQL:

Query1.SQL.Text := 'SELECT * FROM Master WHERE MasterId = 10';
Query1.Open;

Y en EntityDAC para la recepción de objetos o sus colecciones se usa un lenguaje especial: LINQ.

Índice

    ¿Qué es LINQ?

    LINQ es un lenguaje que se especializa en escribir consultas similares a las consultas SQL que se utilizan para recuperar datos de una base de datos y asignarlos a entidades o colecciones de entidades.

    ¿Cuáles son los beneficios de usar LINQ?

    Primero: el programador obtiene una sintaxis universal para escribir consultas, que no depende de las especificaciones de la base de datos utilizada.

    Por ejemplo: la tarea es obtener los primeros 5 registros de la tabla. En MySQL e InterBase, las consultas correspondientes se verán diferentes, lo que debe tenerse en cuenta al escribir una aplicación:

    mysql

    SELECT Name
    FROM Master
    LIMIT 5;

    interbase

    SELECT FIRST 5 Name
    FROM Master;

    Al usar LINQ, será suficiente escribir en el código fuente del programa una solicitud que se ejecutará correctamente independientemente del DBMS utilizado:

    Query := From(Master).Select.Take(5);

    Segundo: el uso de la sintaxis "nativa" de Delphi al escribir consultas le brinda al programador todos los beneficios de un editor de código integrado:

    Editor de código

    Finalmente, al escribir consultas, evite por completo los errores sintácticos y los errores tipográficos.

    Patrón:

    Query1.SQL.Text := 'SELECT Name FROM Master WHER MasterId = 10';

    o

    Query1.SQL.Text := 'SELECT Nam FROM Master WHERE MasterId = 10';

    Con el uso clásico de SQL, tales errores solo aparecerían durante la ejecución de la aplicación. El uso de LINQ minimiza la probabilidad de tales situaciones porque LINQ se prueba en la etapa de compilación de la aplicación.

    La arquitectura LINQ en EntityDAC

    La sintaxis de LINQ se basa en el principio de "cadena de métodos", es decir cada instrucción de consulta subsiguiente es un método para ejecutar la instrucción anterior. Este enfoque elimina el uso de variables intermedias y hace que el código de consulta sea más legible. Por ejemplo, compare el código:

    Query := From(Master).Where(Master.Id = 10).Select;

    con la siguiente estructura:

    a := From(Master);
    b := a.Where(Master.Id = 10)
    c := b.Select;

    Además, el principio de "cadena de métodos" define una estructura de consulta LINQ general que difiere de la estructura de consulta SQL habitual. La construcción de la consulta LINQ se basa en las dos disposiciones siguientes:

    • cada operador de solicitud devuelve un conjunto de objetos;
    • cada operador subsiguiente aplica una acción específica a ese conjunto y devuelve el subconjunto resultante.

    Veamos una consulta de ejemplo:

    Query := From(Master).
             Where(Master.Id > 10).
             OrderBy(Master.Name).
             Select(Master.Name);

    El infierno (maestro) el operador devuelve el conjunto completo de instancias de la entidad Maestra. El siguiente operador Dónde (Id. Maestro > 10) aplica filtro por identificador campo en este conjunto y "pasa" el subconjunto final al siguiente operador. El Ordenar por (nombre del maestro) el operador ordena el subconjunto final por Maestro.Nombre campo y lo pasa. Por fin, Seleccione (nombre del asistente) el operador genera un nuevo subconjunto de objetos que contienen un solo campo Maestro.Nombre. La solicitud generada se guarda en un archivo. Solicitud variable para su posterior ejecución y materialización del resultado.

    Una descripción detallada de la sintaxis de LINQ implementada en EntityDAC está disponible en la sección correspondiente de la documentación de EntityDAC.

    La materialización de los resultados de la consulta significa obtener los resultados de la consulta en forma de objetos o colecciones de objetos utilizando los métodos GetEntity y GetEntities.

    Query := From(Emp).
             Where(Emp.DeptNo = 10).
             Select;
    
    Emps := Context.GetEntities<TEmp>(Query);

    Algunas características de la implementación de LINQ en EntityDAC

    En todos los ejemplos de código de este artículo, la consulta LINQ generada se asigna a la variable Query. La variable para almacenar la solicitud LINQ generada debe declararse de la siguiente manera:

    var
      Query: ILinqQueryable;

    Este enfoque elimina la necesidad de que el programador controle la destrucción de la variable.

    Cualquier consulta LINQ comienza con una indicación de la fuente de datos, es decir, el operador "De". Hay una función global definida en EntidadDAC.Linq Módulo EntityDAC:

    function From(const Source: TExpression): ILinqFrom;

    este es el "punto de partida" para crear una consulta LINQ.

    Artículos de interés

    Subir