Partager via


Différences entre Entity SQL et Transact-SQL

Cette rubrique décrit les différences entre la classe 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 (semblable à oftype dans les séquences C#) fournit cette fonction.

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 qui permettent d'effectuer ces opérations.

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

  • Les jointures s'appliquent aux collections.

Prise en charge des expressions

Transact-SQL a 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 , voir Expressions non prises en charge (Entity SQL).

Les requêtes Entity SQL suivantes sont toutes valides :

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 porté 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, comme suit :

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 uniformément. 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 la clause select et la clause 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 ne l'est pas dans Entity SQL  :

select t.x + t.y from T as t group by t.x + t.y

Pour effectuer cette opération 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 ne l'est pas dans Entity SQL .

select a from T

La 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 d')une 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 de la forme select * from T et select T1.* from T1, T2... peuvent être exprimées dans Entity SQL sous la forme select value t from T as t et select value t1 from T1 as t1, T2 as t2..., respectivement. 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 des 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, la syntaxe Entity SQL  :

select k1, count(t.a), sum(t.a)
from T as t
group by t.b + t.c as k1

...est équivalente à la syntaxe 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 élevé. 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, voir Jeu de caractères d'entrée (Entity SQL).

Fonctionnalités Transact-SQL non disponibles dans Entity SQL

Les fonctionnalités Transact-SQL ci-dessous ne sont pas disponibles 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 des opérateurs intégrés 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 aux magasins déclarées dans le manifeste du fournisseur. De plus, Entity Framework vous permet de déclarer des fonctions de magasin existantes intégrées et définies par l'utilisateur pour les utiliser dans 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 catagories;

Voir aussi

Concepts

Vue d'ensemble d'Entity SQL
Expressions non prises en charge (Entity SQL)