Diferencias entre Entity SQL y Transact-SQL
En este artículo se describen las diferencias entre Entity SQL y Transact-SQL.
Compatibilidad con herencia y relaciones
Entity SQL funciona directamente con esquemas de entidades conceptuales y admite características del modelo conceptual tales como herencia y relaciones.
Cuando se trabaja con la herencia, suele ser útil seleccionar instancias de un subtipo de una colección de instancias de supertipo. El operador oftype de Entity SQL (similar a oftype
en las secuencias de C#) proporciona esta capacidad.
Compatibilidad con colecciones
Entity SQL trata las colecciones como entidades de primera clase. Por ejemplo:
Las expresiones de colecciones son válidas en una cláusula
from
.Las subconsultas
in
yexists
se han generalizado para permitir cualquier tipo de colección.Una subconsulta es un tipo de colección.
e1 in e2
yexists(e)
son las construcciones de Entity SQL que permiten realizar estas operaciones.Las operaciones Set, como
union
,intersect
yexcept
, funcionan ahora en colecciones.Las combinaciones funcionan en colecciones.
Compatibilidad con expresiones
Transact-SQL tiene subconsultas (tablas) y expresiones (filas y columnas).
Para admitir colecciones y colecciones anidadas, Entity SQL convierte todo en una expresión. Entity SQL es más ajustable que Transact SQL: todas las expresiones se pueden utilizar en cualquier parte. Las expresiones de consulta siempre producen colecciones de los tipos proyectados y se pueden utilizar en cualquier parte donde se permita una expresión de colección. Para obtener información sobre las expresiones de Transact-SQL que no se admiten en Entity SQL, consulte Expresiones no admitidas.
A continuación se muestran todas las consultas válidas de Entity SQL:
1+2 *3
"abc"
row(1 as a, 2 as b)
{ 1, 3, 5}
e1 union all e2
set(e1)
Tratamiento uniforme de subconsultas
Dada la importancia de las tablas, Transact-SQL realiza una interpretación contextual de las subconsultas. Por ejemplo, se considera que una subconsulta de la cláusula from
es un conjunto múltiple (tabla). Pero la misma subconsulta utilizada en la cláusula select
se considera una subconsulta escalar. De igual forma, se considera que una subconsulta utilizada en el lado izquierdo de un operador in
es una subconsulta escalar, mientras se espera que en el lado derecho sea una subconsulta de conjunto múltiple.
Entity SQL elimina estas diferencias. Una expresión tiene una interpretación uniforme que no depende del contexto en el que se utiliza. Entity SQL considera que todas las subconsultas son de conjunto múltiple. Si se desea que la subconsulta tenga un valor escalar, Entity SQL proporciona el operador anyelement
que opera en una colección (en este caso, la subconsulta) y extrae el valor singleton de la misma.
Evitar conversiones implícitas en subconsultas
Un efecto secundario relacionado del tratamiento uniforme de las subconsultas es la conversión implícita de las subconsultas en valores escalares. En concreto, en Transact-SQL, un conjunto múltiple de filas (con un campo único) se convierte implícitamente en un valor escalar cuyo tipo de datos es el del campo.
Entity SQL no admite esta coerción implícita. Entity SQL proporciona el operador ANYELEMENT
para extraer un valor singleton de una colección y una cláusula select value
para evitar crear un contenedor de filas durante una expresión de consulta.
Seleccionar el valor: evitar el contenedor de filas implícitas
La cláusula select de una subconsulta de Transact-SQL crea implícitamente un contenedor de filas en torno a los elementos de la cláusula. Esto implica que no podemos crear colecciones de valores escalares o de objetos. Transact-SQL permite una coerción implícita entre un rowtype
con un campo y un valor singleton del mismo tipo de datos.
Entity SQL proporciona la cláusula select value
para omitir la construcción de filas implícitas. Solo se puede especificar un elemento en una cláusula select value
. Cuando se utiliza este tipo de cláusula, no se crea ningún contenedor de filas en torno a los elementos de la cláusula select
y se puede generar una colección de la forma deseada, por ejemplo: select value a
.
Entity SQL también proporciona el constructor de filas para construir filas arbitrarias. La cláusula select
toma uno o más elementos de la proyección y devuelve un registro de datos con campos:
select a, b, c
Correlación izquierda y uso de alias
En Transact-SQL, las expresiones de un ámbito determinado (una cláusula única como select
o from
) no pueden hacer referencia a expresiones definidas anteriormente en el mismo ámbito. Algunos dialectos de SQL (incluido Transact-SQL) admiten formas limitadas de estas en la cláusula from
.
Entity SQL generaliza las correlaciones izquierdas de la cláusula from
y las trata uniformemente. Las expresiones de la cláusula from
pueden hacer referencia a definiciones anteriores (a la izquierda) en la misma cláusula sin necesidad de una sintaxis adicional.
Entity SQL también impone restricciones adicionales en consultas que afectan a cláusulas group by
. Las expresiones de las cláusulas select
y having
de dichas consultas solo pueden hacer referencia a las claves group by
a través de sus alias. La siguiente construcción es válida en Transact-SQL, pero no está en Entity SQL:
SELECT t.x + t.y FROM T AS t group BY t.x + t.y
Para hacerlo en Entity SQL:
SELECT k FROM T AS t GROUP BY (t.x + t.y) AS k
Hacer referencia a columnas (propiedades) de tablas (colecciones)
Todas las referencias de columna de Entity SQL se deben calificar con el alias de la tabla. La construcción siguiente (suponiendo que a
es una columna válida de la tabla T
) es válida en Transact-SQL pero no lo es en Entity SQL.
SELECT a FROM T
El formulario de Entity SQL es
SELECT t.a AS A FROM T AS t
Los alias de tabla son opcionales en la cláusula from
. El nombre de la tabla se utiliza como alias implícito. Entity SQL también permite el formato siguiente:
SELECT Tab.a FROM Tab
Navegación a través de objetos
Transact-SQL usa la notación "." para hacer referencia a las columnas de (una fila de) una tabla. Entity SQL amplía esta notación (que toma prestada de los lenguajes de programación) para admitir la navegación a través de las propiedades de un objeto.
Por ejemplo, si p
es una expresión de tipo Persona, lo siguiente es la sintaxis de Entity SQL para hacer referencia a la ciudad de la dirección de esta persona.
p.Address.City
No hay compatibilidad con *
Transact-SQL admite la sintaxis * sin calificar como alias de la fila completa y la sintaxis * calificada (t.*) como acceso directo para los campos de esa tabla. Además, Transact-SQL permite un agregado count(*) especial, que incluye valores NULL.
Entity SQL no admite la construcción *. Las consultas de Transact-SQL con el formato select * from T
y select T1.* from T1, T2...
se pueden expresar en Entity SQL como select value t from T as t
y select value t1 from T1 as t1, T2 as t2...
, respectivamente. Además, estas construcciones administran la herencia (capacidad de sustitución de valores), mientras que las variantes de select *
se restringen a las propiedades de nivel superior del tipo declarado.
Entity SQL no admite el agregado count(*)
. En su lugar, use count(0)
.
Cambios de Group By
Entity SQL admite el uso de alias de las claves group by
. Las expresiones de la cláusula select
y de la cláusula having
deben hacer referencia a las claves group by
a través de estos alias. Por ejemplo, esta sintaxis de Entity SQL:
SELECT k1, count(t.a), sum(t.a)
FROM T AS t
GROUP BY t.b + t.c AS k1
... es equivalente a la siguiente de Transact-SQL:
SELECT b + c, count(*), sum(a)
FROM T
GROUP BY b + c
Agregados basados en colecciones
Entity SQL admite dos tipos de agregados.
Los agregados basados en colecciones operan en colecciones y generan el resultado agregado. Estos pueden aparecer en cualquier parte de la consulta y no requieren una cláusula group by
. Por ejemplo:
SELECT t.a AS a, count({1,2,3}) AS b FROM T AS t
Entity SQL también admite agregados del estilo de SQL. Por ejemplo:
SELECT a, sum(t.b) FROM T AS t GROUP BY t.a AS a
Uso de la cláusula ORDER BY
Transact-SQL permite especificar cláusulas ORDER BY
solo en el bloque SELECT .. FROM .. WHERE
. En Entity SQL, puede utilizar una expresión ORDER BY
anidada que se puede colocar en cualquier parte de la consulta, pero la ordenación de una consulta anidada no se conserva.
-- The following query will order the results by the last name
SELECT C1.FirstName, C1.LastName
FROM AdventureWorks.Contact AS C1
ORDER BY C1.LastName
-- In the following query ordering of the nested query is ignored.
SELECT C2.FirstName, C2.LastName
FROM (SELECT C1.FirstName, C1.LastName
FROM AdventureWorks.Contact as C1
ORDER BY C1.LastName) as C2
Identificadores
En Transact-SQL, la comparación del identificador está basada en la intercalación de la base de datos actual. En Entity SQL, los identificadores no incluyen nunca distinción entre mayúsculas y minúsculas, pero tienen en cuenta los acentos (es decir, Entity SQL distingue entre caracteres con y sin acento; por ejemplo, "e" no es igual a "é"). Entity SQL trata las versiones de letras que parecen iguales pero proceden de páginas de códigos diferentes como caracteres distintos. Para más información, consulte Juego de caracteres de entrada.
Funcionalidad de Transact-SQL no disponible en Entity SQL
La siguiente funcionalidad de Transact-SQL no está disponible en Entity SQL.
DML
Entity SQL no proporciona actualmente compatibilidad con las instrucciones DML (inserción, actualización, eliminación).
DDL
Entity SQL no proporciona compatibilidad con DDL en la versión actual.
Programación imperativa
Entity SQL no proporciona compatibilidad con la programación imperativa, a diferencia de Transact-SQL. Utilice un lenguaje de programación en su lugar.
Funciones de agrupamiento
Entity SQL no proporciona aún compatibilidad con las funciones de agrupamiento (por ejemplo, CUBE, ROLLUP y GROUPING_SET).
Funciones analíticas
Entity SQL no proporciona aún compatibilidad con las funciones analíticas.
Funciones y operadores integrados
Entity SQL admite un subconjunto de funciones y operadores integrados de Transact-SQL. Es probable que estos operadores y funciones sean admitidos por los principales proveedores de almacenamiento. Entity SQL utiliza las funciones específicas del almacén declaradas en un manifiesto del proveedor. Además, Entity Framework permite declarar funciones de almacenamiento existentes integradas y definidas por el usuario, para usarlas en Entity SQL.
Sugerencias
Entity SQL no proporciona mecanismos para sugerencias de consulta.
Resultados de un consulta por lotes
Entity SQL no admite resultados de una consulta por lotes. Por ejemplo, el siguiente código es válido en Transact-SQL (cuando se envía como un lote):
SELECT * FROM products;
SELECT * FROM categories;
Sin embargo, no se admite el código de Entity SQL equivalente:
SELECT value p FROM Products AS p;
SELECT value c FROM Categories AS c;
Entity SQL admite únicamente una instrucción de consulta que genera un solo resultado por comando.