Tradução do LINQ to NoSQL no Azure Cosmos DB for NoSQL
APLICA-SE A: NoSQL
O provedor de consultas do Azure Cosmos DB realiza um mapeamento de melhor esforço de uma consulta LINQ para uma consulta do Azure Cosmos DB for NoSQL. Se você quiser obter a consulta NoSQL que é convertida do LINQ, use o método ToString()
no objeto IQueryable
gerado. A descrição a seguir pressupõe uma familiaridade básica com o LINQ. Além do LINQ, o Azure Cosmos DB também suporta Entity Framework Core, que funciona com a API para NoSQL.
Observação
Recomendamos o uso da versão mais recente do SDK do .NET(Microsoft.Azure.Cosmos
)
O sistema de tipo de provedor de consulta suporta apenas os tipos primitivos JSON: numeric
, Boolean
, string
e null
.
O provedor de consultas oferece suporte às seguintes expressões escalares:
Valores constantes, inclusive valores constantes dos tipos de dados primitivos no momento de avaliação da consulta.
Expressões de índice de propriedade/matriz – que se refere à propriedade de um objeto ou um elemento de matriz. Por exemplo:
family.Id; family.children[0].familyName; family.children[0].grade;
int n = 1; family.children[n].grade;
Expressões aritméticas, inclusive expressões aritméticas comuns em valores numéricos e boolianos.
2 * family.children[0].grade; x + y;
Expressão de comparação de cadeias de caracteres, o que inclui a comparação de um valor de cadeia de caracteres a um valor constante de cadeia de caracteres.
mother.familyName.StringEquals("Wakefield");
string s = "Rob"; string e = "in"; string c = "obi"; child.givenName.StartsWith(s); child.givenName.EndsWith(e); child.givenName.Contains(c);
Expressão de criação de objeto/matriz, que retorna um objeto do tipo de valor composto ou tipo anônimo ou uma matriz desses objetos. Você pode aninhar esses valores.
new Parent { familyName = "Wakefield", givenName = "Robin" }; new { first = 1, second = 2 }; //an anonymous type with two fields new int[] { 3, child.grade, 5 };
Usando o LINQ
Você pode criar uma consulta LINQ com GetItemLinqQueryable
. Este exemplo mostra a geração de consulta LINQ e a execução assíncrona com um FeedIterator
:
using FeedIterator<Book> setIterator = container.GetItemLinqQueryable<Book>()
.Where(b => b.Title == "War and Peace")
.ToFeedIterator<Book>());
//Asynchronous query execution
while (setIterator.HasMoreResults)
{
foreach(var item in await setIterator.ReadNextAsync()){
{
Console.WriteLine(item.cost);
}
}
Operadores LINQ com suporte
O provedor LINQ incluído no SDK do .NET do NoSQL dá suporte aos seguintes operadores:
- Select: as projeções são convertidas para SELECT, incluindo a construção de objetos.
- Em que: os filtros são convertidos para WHERE e dão suporte à conversão entre
&&
,||
e!
para operadores do NoSQL - SelectMany: permite o desenrolamento de matrizes à cláusula SQL JOIN. Use para encadear ou aninhar expressões para filtrar elementos de matriz.
- OrderBy e OrderByDescending: converte para ORDER BY com ASC ou DESC.
- Operadores Count, Sum, Min, Max e Average para agregação e os seus equivalentes assíncronos, CountAsync, SumAsync, MinAsync, MaxAsync e AverageAsync.
- CompareTo: é convertido em comparações de intervalo. Esse operador é comumente usado em cadeia de caracteres, pois elas não são comparáveis no .NET.
- Skip e Take: converte para OFFSET e LIMIT para limitar os resultados de uma consulta e fazer a paginação.
- Funções matemáticas: dá suporte à conversão do .NET
Abs
,Acos
,Asin
,Atan
,Ceiling
,Cos
,Exp
,Floor
,Log
,Log10
,Pow
,Round
,Sign
,Sin
,Sqrt
,Tan
eTruncate
para as funções matemáticas internas equivalentes. - Funções de cadeia de caracteres: dá suporte à conversão do .NET
Concat
,Contains
,Count
,EndsWith
,IndexOf
,Replace
,Reverse
,StartsWith
,SubString
,ToLower
,ToUpper
,TrimEnd
eTrimStart
para as funções de matriz internas equivalentes. - Funções de matriz: oferece suporte à conversão do .NET
Concat
,Contains
eCount
para as funções de matriz internas equivalentes. - Funções de extensão geoespacial: dão suporte à conversão dos métodos
Distance
,IsValid
,IsValidDetailed
eWithin
para funções geoespaciais internas equivalentes. - Função de Extensão de Função Definida pelo Usuário: Apoia a tradução do método stub CosmosLinq.InvokeUserDefinedFunction para a função correspondente definida pelo usuário.
- Diversos: dá suporte à conversão de
Coalesce
e operadores condicionais. Pode converterContains
para a Cadeia de caracteres CONTAINS, ARRAY_CONTAINS ou IN, dependendo do contexto.
Exemplos
Os exemplos a seguir ilustram como alguns dos operadores de consulta LINQ padrão são convertidos em consultas no Azure Cosmos DB.
Seleção de operador
A sintaxe é input.Select(x => f(x))
, em que f
é uma expressão escalar. Neste caso, o input
é um objeto IQueryable
.
Selecione o operador, exemplo 1:
Expressão lambda do LINQ
input.Select(family => family.parents[0].familyName);
NoSQL
SELECT VALUE f.parents[0].familyName FROM Families f
Selecione o operador, exemplo 2:
Expressão lambda do LINQ
input.Select(family => family.children[0].grade + c); // c is an int variable
NoSQL
SELECT VALUE f.children[0].grade + c FROM Families f
Selecione o operador, exemplo 3:
Expressão lambda do LINQ
input.Select(family => new { name = family.children[0].familyName, grade = family.children[0].grade + 3 });
NoSQL
SELECT VALUE { "name":f.children[0].familyName, "grade": f.children[0].grade + 3 } FROM Families f
Operador SelectMany
A sintaxe é input.SelectMany(x => f(x))
, em que f
é uma expressão escalar que retorna um tipo de contêiner.
Expressão lambda do LINQ
input.SelectMany(family => family.children);
NoSQL
SELECT VALUE child FROM child IN Families.children
Operador Where
A sintaxe é input.Where(x => f(x))
, em que f
é uma expressão escalar que retorna um valor booliano.
Operador Where, exemplo 1:
Expressão lambda do LINQ
input.Where(family=> family.parents[0].familyName == "Wakefield");
NoSQL
SELECT * FROM Families f WHERE f.parents[0].familyName = "Wakefield"
Operador Where, exemplo 2:
Expressão lambda do LINQ
input.Where( family => family.parents[0].familyName == "Wakefield" && family.children[0].grade < 3);
NoSQL
SELECT * FROM Families f WHERE f.parents[0].familyName = "Wakefield" AND f.children[0].grade < 3
Consultas NoSQL compostas
Você pode compor os operadores anteriores para formar consultas mais poderosas. Como o Azure Cosmos DB dá suporte a contêineres aninhados, você pode concatenar ou aninhar a composição.
Concatenação
A sintaxe é input(.|.SelectMany())(.Select()|.Where())*
. Uma consulta concatenada pode ser iniciada por uma consulta SelectMany
opcional, seguida por múltiplos operadores Select
ou Where
.
Concatenação, exemplo 1:
Expressão lambda do LINQ
input.Select(family => family.parents[0]) .Where(parent => parent.familyName == "Wakefield");
NoSQL
SELECT * FROM Families f WHERE f.parents[0].familyName = "Wakefield"
Concatenação, exemplo 2:
Expressão lambda do LINQ
input.Where(family => family.children[0].grade > 3) .Select(family => family.parents[0].familyName);
NoSQL
SELECT VALUE f.parents[0].familyName FROM Families f WHERE f.children[0].grade > 3
Concatenação, exemplo 3:
Expressão lambda do LINQ
input.Select(family => new { grade=family.children[0].grade}). Where(anon=> anon.grade < 3);
NoSQL
SELECT * FROM Families f WHERE ({grade: f.children[0].grade}.grade > 3)
Concatenação, exemplo 4:
Expressão lambda do LINQ
input.SelectMany(family => family.parents) .Where(parent => parents.familyName == "Wakefield");
NoSQL
SELECT * FROM p IN Families.parents WHERE p.familyName = "Wakefield"
Aninhamento
A sintaxe é input.SelectMany(x=>x.Q())
, em que Q
é um operador Select
, SelectMany
ou Where
.
Uma consulta aninhada aplica a consulta interior a cada elemento do contêiner externo. Um recurso importante é que a consulta interna pode se referir aos campos dos elementos no contêiner exterior, como uma autojunção.
Aninhamento, exemplo 1:
Expressão lambda do LINQ
input.SelectMany(family=> family.parents.Select(p => p.familyName));
NoSQL
SELECT VALUE p.familyName FROM Families f JOIN p IN f.parents
Aninhamento, exemplo 2:
Expressão lambda do LINQ
input.SelectMany(family => family.children.Where(child => child.familyName == "Jeff"));
NoSQL
SELECT * FROM Families f JOIN c IN f.children WHERE c.familyName = "Jeff"
Aninhamento, exemplo 3:
Expressão lambda do LINQ
input.SelectMany(family => family.children.Where( child => child.familyName == family.parents[0].familyName));
NoSQL
SELECT * FROM Families f JOIN c IN f.children WHERE c.familyName = f.parents[0].familyName