Partager via


Différences entre Entity SQL et Transact-SQL

Cet article décrit les différences entre Entity SQL et Transact-SQL.

Héritage et prise en charge des relations

Entity SQL fonctionne directement avec les schémas d’entité conceptuels et prend en charge des fonctionnalités de modèle conceptuel, telles que l’héritage et les relations.

Lors de l’utilisation de l’héritage, il est souvent utile de sélectionner des instances d’un sous-type à partir d’une collection d’instances de supertype. L’opérateur oftype dans Entity SQL (similaire à oftype dans les séquences C#) fournit cette fonctionnalité.

Prise en charge des collections

Entity SQL traite les collections comme des entités de première classe. Par exemple :

  • Les expressions de collection sont valides dans une clause from.

  • Les sous-requêtes in et exists ont été généralisées pour autoriser toute collection.

    Une sous-requête est un type de collection. e1 in e2 et exists(e) sont les constructions Entity SQL permettant d’effectuer ces opérations.

  • Les opérations de définition, telles que union, intersect et except, s’appliquent à présent aux collections.

  • Les jointures s’appliquent aux collections.

Prise en charge des expressions

Transact-SQL comprend des sous-requêtes (tables) et des expressions (lignes et colonnes).

Pour prendre en charge les collections et les collections imbriquées, Entity SQL transforme tout en expression. Entity SQL est plus composable que Transact-SQL. Chaque expression peut être utilisée n’importe où. Les expressions de requête génèrent toujours des collections des types projetés et peuvent être utilisées partout où une expression de collection est autorisée. Pour plus d’informations sur les expressions Transact-SQL qui ne sont pas prises en charge dans Entity SQL, consultez Expressions non prises en charge.

Les requêtes Entity SQL valides sont les suivantes :

1+2 *3  
"abc"  
row(1 as a, 2 as b)  
{ 1, 3, 5}
e1 union all e2  
set(e1)  

Traitement uniforme des sous-requêtes

Vu l’accent mis sur les tables, Transact-SQL effectue une interprétation contextuelle des sous-requêtes. Par exemple, une sous-requête dans la clause from est considérée comme un multiset (table). En revanche, la même sous-requête utilisée dans la clause select est considérée comme une sous-requête scalaire. De la même façon, une sous-requête utilisée à gauche d’un opérateur in est considérée comme sous-requête scalaire, tandis que le côté droit est supposé être une sous-requête de type multiset.

Entity SQL élimine ces différences. Une expression a une interprétation uniforme qui ne dépend pas du contexte dans lequel elle est utilisée. Entity SQL considère toutes les sous-requêtes comme des sous-requêtes de type multiset. Si une valeur scalaire est souhaitée à partir de la sous-requête, Entity SQL fournit l’opérateur anyelement qui opère sur une collection (dans le cas présent, la sous-requête) et extrait une valeur singleton de la collection.

Éviter des contraintes implicites pour les sous-requêtes

Un effet secondaire connexe du traitement uniforme des sous-requêtes est la conversion implicite des sous-requêtes en valeurs scalaires. En particulier, dans Transact-SQL, un multiset de lignes (avec un champ unique) est converti implicitement en une valeur scalaire dont le type de données est celui du champ.

Entity SQL ne prend pas en charge cette contrainte implicite. Entity SQL fournit l’opérateur ANYELEMENT pour extraire une valeur singleton d’une collection, et une clause select value pour éviter de créer un wrapper de ligne pendant une expression de requête.

Select Value : éviter le wrapper de ligne implicite

La clause select dans une sous-requête Transact-SQL crée implicitement un wrapper de ligne autour des éléments de la clause. Cela implique que nous ne pouvons pas créer de collections de scalaires ou d’objets. Transact-SQL autorise une contrainte implicite entre un rowtype avec un champ et une valeur singleton du même type de données.

Entity SQL fournit la clause select value pour ignorer la construction de ligne implicite. Un seul élément peut être spécifié dans une clause select value. Lorsqu’une telle clause est utilisée, aucun wrapper de ligne n’est construit autour des éléments de la clause select et une collection de la forme souhaitée peut être générée, par exemple, select value a.

Entity SQL fournit également le constructeur de ligne pour construire des lignes arbitraires. select accepte un ou plusieurs éléments de la projection et produit un enregistrement de données avec des champs :

select a, b, c

Corrélation gauche et utilisation d'alias

Dans Transact-SQL, les expressions comprises dans une étendue donnée (une clause unique comme select ou from) ne peuvent pas référencer des expressions définies précédemment dans la même étendue. Certains dialectes SQL (y compris Transact-SQL) prennent en charge des formes limitées de ces éléments dans la clause from.

Entity SQL généralise les corrélations gauches dans la clause from et les traite de manière uniforme. Les expressions dans la clause from peuvent référencer des définitions antérieures (définitions à gauche) dans la même clause sans nécessiter une syntaxe supplémentaire.

Entity SQL impose également des restrictions supplémentaires sur les requêtes qui impliquent des clauses group by. Les expressions dans les clauses select et having de telles requêtes peuvent faire référence uniquement aux clés group by par le biais de leurs alias. La construction suivante est valide dans Transact-SQL, mais pas dans Entity SQL :

SELECT t.x + t.y FROM T AS t group BY t.x + t.y

Pour faire cela dans Entity SQL :

SELECT k FROM T AS t GROUP BY (t.x + t.y) AS k

Référencement de colonnes (propriétés) de tables (collections)

Toutes les références de colonne dans Entity SQL doivent être qualifiées avec l’alias de la table. La construction suivante (en supposant que a est une colonne valide de la table T) est valide dans Transact-SQL mais pas dans Entity SQL.

SELECT a FROM T

Le forme Entity SQL est

SELECT t.a AS A FROM T AS t

Les alias de la table sont facultatifs dans la clause from. Le nom de la table est utilisé comme alias implicite. Entity SQL autorise également la forme suivante :

SELECT Tab.a FROM Tab

Transact-SQL utilise la notation "." pour référencer les colonnes d’une (ligne de) table. Entity SQL étend cette notation (empruntée des langages de programmation) pour prendre en charge la navigation dans les propriétés d’un objet.

Par exemple, si p est une expression de type Person, la syntaxe Entity SQL ci-dessous référence la ville de l’adresse de cette personne.

p.Address.City

Aucune prise en charge pour *

Transact-SQL prend en charge la syntaxe non qualifiée * comme alias pour la ligne entière, ainsi que la syntaxe qualifiée * (t.*) comme raccourci pour les champs de cette table. De plus, Transact-SQL permet l’utilisation d’un agrégat count(*) spécial, qui inclut les valeurs Null.

Entity SQL ne prend pas en charge la construction *. Les requêtes Transact-SQL sous les formes select * from T et select T1.* from T1, T2... peuvent être exprimées dans Entity SQL respectivement sous les formes select value t from T as t et select value t1 from T1 as t1, T2 as t2.... En outre, ces constructions gèrent l'héritage (capacité des valeurs à être substituées), tandis que les variantes select * sont restreintes aux propriétés de niveau supérieur du type déclaré.

Entity SQL ne prend pas en charge l’agrégat count(*). Utilisez count(0) à la place.

Modifications apportées à Group By

Entity SQL prend en charge les alias de clés group by. Les expressions dans la clause select et la clause having doivent faire référence aux clés group by par le biais de ces alias. Par exemple, cette syntaxe Entity SQL :

SELECT k1, count(t.a), sum(t.a)
FROM T AS t
GROUP BY t.b + t.c AS k1

... équivaut à la commande Transact-SQL suivante :

SELECT b + c, count(*), sum(a)
FROM T
GROUP BY b + c

Agrégats basés sur des collections

Entity SQL prend en charge deux types d’agrégats.

Les agrégats basés sur des collections opèrent sur des collections et produisent le résultat agrégé. Ils peuvent apparaître n'importe où dans la requête et ne requièrent pas de clause group by. Par exemple :

SELECT t.a AS a, count({1,2,3}) AS b FROM T AS t

Entity SQL prend également en charge les agrégats de style SQL. Par exemple :

SELECT a, sum(t.b) FROM T AS t GROUP BY t.a AS a

Utilisation des clauses ORDER BY

Transact-SQL permet de spécifier des clauses ORDER BY uniquement dans le bloc SELECT .. FROM .. WHERE le plus haut. Dans Entity SQL, vous pouvez utiliser une expression ORDER BY imbriquée et elle peut être placée n’importe où dans la requête, mais le classement dans une requête imbriquée n’est pas conservé.

-- 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  

Identificateurs

Dans Transact-SQL, la comparaison d’identificateurs est basée sur le classement de la base de données actuelle. Dans Entity SQL, les identificateurs respectent toujours la casse et les accents (autrement dit, Entity SQL distingue les caractères accentués et non accentués ; par exemple, « a » n’est pas égal à « à »). Entity SQL traite les versions des lettres qui apparaissent identiques mais qui proviennent de pages de codes différentes comme des caractères différents. Pour plus d’informations, consultez Jeu de caractères d’entrée.

Fonctionnalités Transact-SQL non disponibles dans Entity SQL

La fonctionnalité Transact-SQL suivante n’est pas disponible dans Entity SQL.

DML
Entity SQL ne fournit actuellement aucune prise en charge pour les instructions DML (insert, update, delete).

DDL
Entity SQL ne fournit aucune prise en charge pour DDL dans la version actuelle.

Programmation impérative
Entity SQL ne fournit aucune prise en charge pour la programmation impérative, contrairement à Transact-SQL. Utilisez un langage de programmation à la place.

Fonctions de regroupement
Entity SQL ne fournit pas encore de prise en charge pour les fonctions de regroupement (par exemple, CUBE, ROLLUP et GROUPING_SET).

Fonctions analytiques
Entity SQL ne fournit pas (encore) de prise en charge pour les fonctions analytiques.

Fonctions et opérateurs intégrés
Entity SQL prend en charge un sous-ensemble des fonctions et opérateurs intégrés de Transact-SQL. Ces opérateurs et ces fonctions seront vraisemblablement pris en charge par les principaux fournisseurs de stockage. Entity SQL utilise les fonctions spécifiques des magasins déclarées dans le manifeste du fournisseur. De plus, l’Entity Framework vous permet de déclarer des fonctions de magasin existantes intégrées et définies par l’utilisateur à l’usage d’Entity SQL.

Indicateurs
Entity SQL ne fournit pas de mécanismes pour les indicateurs de requête.

Résultats d'une requête de traitement par lot
Entity SQL ne prend pas en charge les résultats d’une requête de traitement par lot. Par exemple, ce qui suit est valide pour Transact-SQL (envoi en tant que lot) :

SELECT * FROM products;
SELECT * FROM categories;

En revanche, l’équivalent Entity SQL n’est pas pris en charge :

SELECT value p FROM Products AS p;
SELECT value c FROM Categories AS c;

Entity SQL ne prend en charge qu’une seule instruction de requête générant un résultat par commande.

Voir aussi