Partilhar via


Como o Entity SQL difere do Transact-SQL

Este artigo descreve as diferenças entre Entity SQL e Transact-SQL.

Suporte de Herança e Relacionamentos

O Entity SQL trabalha diretamente com esquemas de entidade conceitual e oferece suporte a recursos de modelo conceitual, como herança e relacionamentos.

Ao trabalhar com herança, geralmente é útil selecionar instâncias de um subtipo a partir de uma coleção de instâncias de supertipo. O operador oftype no Entity SQL (semelhante ao oftype C# Sequences) fornece esse recurso.

Apoio a Coleções

O Entity SQL trata as coleções como entidades de primeira classe. Por exemplo:

  • As expressões de coleção são válidas numa from cláusula.

  • in e exists as duas subconsultas foram generalizadas de forma a permitir quaisquer coleções.

    Uma subconsulta é um tipo de coleção. e1 in e2 e exists(e) são as construções do Entity SQL para executar essas operações.

  • Operações de conjunto, como union, intersecte except, agora operam em coleções.

  • As junções operam em coleções.

Suporte para expressões

Transact-SQL tem subconsultas (tabelas) e expressões (linhas e colunas).

Para dar suporte a coleções e coleções aninhadas, o Entity SQL torna tudo uma expressão. O Entity SQL é mais componível do que o Transact-SQL — cada expressão pode ser usada em qualquer lugar. As expressões de consulta sempre resultam em coleções dos tipos projetados e podem ser usadas em qualquer lugar em que uma expressão de coleção seja permitida. Para obter informações sobre expressões Transact-SQL que não são suportadas no Entity SQL, consulte Expressões sem suporte.

A seguir estão todas as consultas válidas do Entity SQL:

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

Tratamento uniforme de subconsultas

Dada a sua ênfase em tabelas, Transact-SQL realiza interpretação contextual de subconsultas. Por exemplo, uma subconsulta na from cláusula é considerada um conjunto múltiplo (tabela). Mas a mesma subconsulta usada na select cláusula é considerada uma subconsulta escalar. Da mesma forma, uma subconsulta usada do lado esquerdo de um operador in é considerada como uma subconsulta escalar, enquanto o lado direito é esperado ser uma subconsulta multiconjunto.

O Entity SQL elimina essas diferenças. Uma expressão tem uma interpretação uniforme que não depende do contexto em que é utilizada. O Entity SQL considera todas as subconsultas como subconsultas de vários conjuntos. Se um valor escalar for desejado da subconsulta, o Entity SQL fornecerá o anyelement operador que opera em uma coleção (neste caso, a subconsulta) e extrairá um valor singleton da coleção.

Evitando Coerções Implícitas nas Subconsultas

Um efeito colateral relacionado ao tratamento uniforme de subconsultas é a conversão implícita de subconsultas em valores escalares. Especificamente, no Transact-SQL, um conjunto múltiplo de linhas (com um único campo) é implicitamente convertido em um valor escalar cujo tipo de dados é o do campo.

O Entity SQL não suporta essa coerção implícita. O Entity SQL fornece o operador ANYELEMENT para extrair um valor singleton de uma coleção e a cláusula select value para evitar a criação de um envoltório de linha durante uma expressão de consulta.

Selecionar valor: Evitando o wrapper de linha implícito

A cláusula SELECT numa subconsulta Transact-SQL envolve implicitamente os itens numa estrutura de linha. Isso implica que não podemos criar coleções de escalares ou objetos. Transact-SQL permite uma coerção implícita entre um rowtype com um campo e um valor singleton do mesmo tipo de dados.

O Entity SQL fornece a select value cláusula para ignorar a construção de linha implícita. Só pode ser especificado um elemento numa select value cláusula. Quando tal cláusula é usada, não é construído nenhum envoltório de linha em torno dos itens da cláusula select, e uma coleção da forma desejada pode ser produzida, por exemplo, select value a.

Entity SQL também fornece o construtor de linha para construir linhas arbitrárias. select Pega um ou mais elementos na projeção e resulta em um registro de dados com campos:

select a, b, c

Correlação esquerda e aliasing

No Transact-SQL, expressões em um determinado escopo (uma única cláusula como select ou from) não podem fazer referência a expressões definidas anteriormente no mesmo escopo. Alguns dialetos do SQL (incluindo Transact-SQL) suportam formas limitadas destes na from cláusula.

Entity SQL generaliza as correlações à esquerda na cláusula from e as trata uniformemente. As expressões na cláusula podem fazer referência às definições anteriores from (definições à esquerda) na mesma cláusula sem a necessidade de sintaxe adicional.

O Entity SQL também impõe restrições adicionais a consultas que envolvem group by cláusulas. As expressões na cláusula select e na cláusula having de tais consultas só podem referir-se às chaves através dos seus pseudónimos group by. A construção a seguir é válida no Transact-SQL mas não está no Entity SQL:

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

Para fazer isso no Entity SQL:

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

Referenciando colunas (propriedades) de tabelas (coleções)

Todas as referências de coluna no Entity SQL devem ser qualificadas com o alias de tabela. A construção a seguir (assumindo que a é uma coluna válida de tabela T) é válida em Transact-SQL mas não em Entity SQL.

SELECT a FROM T

O formulário Entity SQL é

SELECT t.a AS A FROM T AS t

Os aliases de tabela são opcionais na from cláusula. O nome da tabela é usado como o alias implícito. O Entity SQL também permite o seguinte formulário:

SELECT Tab.a FROM Tab

Transact-SQL usa a notação "." para referenciar colunas de (uma linha de) uma tabela. O Entity SQL estende essa notação (emprestada de linguagens de programação) para dar suporte à navegação através das propriedades de um objeto.

Por exemplo, se p for uma expressão do tipo Person, a seguir está a sintaxe Entity SQL para fazer referência à cidade do endereço dessa pessoa.

p.Address.City

Sem suporte para *

Transact-SQL suporta a sintaxe * não qualificada como um alias para toda a linha e a sintaxe * qualificada (t.*) como um atalho para os campos dessa tabela. Além disso, Transact-SQL permite uma função de agregação especial count(*), que inclui nulos.

Entity SQL não suporta a construção *. Transact-SQL consultas do formulário select * from T e select T1.* from T1, T2... podem ser expressas em Entity SQL como select value t from T as t e select value t1 from T1 as t1, T2 as t2..., respectivamente. Além disso, essas construções manipulam herança (substituibilidade de valor), enquanto as select * variantes são restritas a propriedades de nível superior do tipo declarado.

O Entity SQL não suporta a count(*) agregação. Utilize count(0) em substituição.

Alterações ao Agrupar Por

O Entity SQL suporta atribuir alias a chaves group by. As expressões na cláusula select e na cláusula having devem referir-se às chaves group by através destes pseudónimos. Por exemplo, esta sintaxe Entity SQL:

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

... é equivalente ao seguinte Transact-SQL:

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

Collection-Based Agregados

O Entity SQL suporta dois tipos de agregações.

Os agregados baseados em coleções operam em coleções e produzem o resultado agregado. Eles podem aparecer em qualquer lugar na consulta e não exigem uma group by cláusula. Por exemplo:

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

O Entity SQL também oferece suporte a agregações no estilo SQL. Por exemplo:

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

Utilização da cláusula ORDER BY

Transact-SQL permite que as cláusulas ORDER BY sejam especificadas apenas no bloco mais externo SELECT .. FROM .. WHERE. No Entity SQL, você pode usar uma expressão aninhada ORDER BY e ela pode ser colocada em qualquer lugar da consulta, mas a ordenação em uma consulta aninhada não é preservada.

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

No Transact-SQL, a comparação de identificadores é baseada no agrupamento do banco de dados atual. No Entity SQL, os identificadores são sempre insensíveis a maiúsculas e minúsculas e sensíveis a acentos (ou seja, o Entity SQL distingue entre caracteres acentuados e não acentuados; por exemplo, 'a' não é igual a 'ấ'). O Entity SQL trata versões de letras que parecem iguais, mas são de páginas de código diferentes, como caracteres diferentes. Para obter mais informações, consulte Conjunto de caracteres de entrada.

Transact-SQL funcionalidade não disponível no Entity SQL

A funcionalidade Transact-SQL a seguir não está disponível no Entity SQL.

DML
Atualmente, o Entity SQL não fornece suporte para instruções DML (inserir, atualizar, excluir).

Linguagem de Definição de Dados (DDL)
O Entity SQL não fornece suporte para DDL na versão atual.

Programação Imperativa
O Entity SQL não fornece suporte para programação imperativa, ao contrário do Transact-SQL. Em vez disso, use uma linguagem de programação.

Funções de agrupamento
O Entity SQL ainda não fornece suporte para funções de agrupamento (por exemplo, CUBE, ROLLUP e GROUPING_SET).

Funções de Análise
O Entity SQL (ainda) não fornece suporte para funções analíticas.

Funções integradas, operadores
O Entity SQL suporta um subconjunto de funções e operadores integrados do Transact-SQL. É provável que estes operadores e funções sejam suportados pelos principais fornecedores de lojas. O Entity SQL usa as funções específicas do repositório declaradas em um manifesto do provedor. Além disso, o Entity Framework permite que você declare funções de armazenamento existentes internas e definidas pelo usuário, para uso do Entity SQL.

Sugestões
O Entity SQL não fornece mecanismos para sugestões de consulta.

Resultados da consulta em lote
O Entity SQL não oferece suporte a resultados de consultas em lote. Por exemplo, o seguinte é válido Transact-SQL (envio em lote):

SELECT * FROM products;
SELECT * FROM categories;

No entanto, o equivalente Entity SQL não é suportado:

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

O Entity SQL suporta apenas uma instrução de consulta que produz resultados por comando.

Ver também