Como o Entity SQL difere do Transact-SQL
Este artigo descreve as diferenças entre Entity SQL e Transact-SQL.
Suporte a 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 em uma
from
cláusula.in
eexists
as subconsultas foram generalizadas para permitir quaisquer coleções.Uma subconsulta é um tipo de coleção.
e1 in e2
eexists(e)
são as construções do Entity SQL para executar essas operações.Operações de conjunto, como
union
,intersect
eexcept
, agora operam em coleções.As junções funcionam em cobranças.
Suporte para expressões
O 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, o Transact-SQL executa a 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 no lado esquerdo de um in
operador é considerada uma subconsulta escalar, enquanto o lado direito deve 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 para 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 ao ANYELEMENT
operador para extrair um valor singleton de uma coleção e uma select value
cláusula para evitar a criação de um wrapper de linha durante uma expressão de consulta.
Selecionar valor: Evitando o wrapper de linha implícito
A cláusula select em uma subconsulta Transact-SQL cria implicitamente um wrapper de linha em torno dos itens na cláusula. Isso implica que não podemos criar coleções de escalares ou objetos. O 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, nenhum invólucro de linha é construído em torno dos itens da select
cláusula, 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 o Transact-SQL) suportam formas limitadas destes na from
cláusula.
A entidade SQL generaliza as from
correlações à esquerda na cláusula e as trata uniformemente. As expressões na cláusula podem fazer referência a from
definições anteriores (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 e having
cláusula select
de tais consultas só podem referir-se às chaves através dos group by
seus pseudónimos. 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 (supondo que a
seja uma coluna válida de tabela T
) é válida no Transact-SQL, mas não no 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
Navegação através de objetos
O 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 *
O 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, o Transact-SQL permite uma agregação count(*) especial, que inclui nulls.
Entity SQL não suporta a construção *. Consultas Transact-SQL 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 Grupo Por
O Entity SQL suporta aliasing de group by
chaves. As expressões na cláusula e having
cláusula select
devem referir-se às group by
chaves 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
Agregados baseados em coleções
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
O Transact-SQL permite que ORDER BY
as cláusulas sejam especificadas apenas no bloco superior 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
Identifiers
No Transact-SQL, a comparação de identificadores é baseada no agrupamento do banco de dados atual. No Entity SQL, os identificadores são sempre sensíveis a maiúsculas e minúsculas e acentuados (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.
Funcionalidade Transact-SQL não disponível no Entity SQL
A seguinte funcionalidade Transact-SQL não está disponível no Entity SQL.
DML
Atualmente, o Entity SQL não fornece suporte para instruções DML (inserir, atualizar, excluir).
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 dicas 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 (enviando como um 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.