Compartilhar via


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 e Truncate 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 e TrimStart para as funções de matriz internas equivalentes.
  • Funções de matriz: oferece suporte à conversão do .NET Concat, Contains e Count 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 e Within 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 converter Contains 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