Condividi tramite


Conversione LINQ to NoSQL in Azure Cosmos DB per NoSQL

SI APPLICA A: NoSQL

Il provider di query di Azure Cosmos DB esegue un mapping ottimale da una query LINQ a una query Di Azure Cosmos DB per NoSQL. Se si vuole ottenere la query NoSQL tradotta da LINQ, usare il ToString() metodo nell'oggetto generato IQueryable . La descrizione seguente presuppone una conoscenza di base di LINQ. Oltre a LINQ, Azure Cosmos DB supporta anche Entity Framework Core, che funziona con l'API per NoSQL.

Nota

È consigliabile usare la versione più recente di .NET SDK (Microsoft.Azure.Cosmos)

Il sistema di tipi di provider di query supporta solo i tipi primitivi JSON: numeric, Booleanstring, e null.

Il provider di query supporta le espressioni scalari seguenti:

  • Valori costanti, inclusi i valori costanti dei tipi di dati primitivi in fase di valutazione delle query.

  • Espressioni indice della matrice/di proprietà che si riferiscono alla proprietà di un oggetto o di un elemento matrice. Ad esempio:

    family.Id;
    family.children[0].familyName;
    family.children[0].grade;
    
    int n = 1;
    
    family.children[n].grade;
    
  • Espressioni aritmetiche, includono espressioni aritmetiche comuni su valori numerici e booleani.

    2 * family.children[0].grade;
    x + y;
    
  • Espressioni di confronto stringhe, che includono il confronto di un valore di stringa con un valore di stringa costante.

    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);
    
  • Espressioni di creazione oggetto/matrice che restituiscono un oggetto di tipo valore composito o tipo anonimo o ancora un matrice di tali oggetti. È possibile annidare questi valori.

    new Parent { familyName = "Wakefield", givenName = "Robin" };
    new { first = 1, second = 2 }; //an anonymous type with two fields  
    new int[] { 3, child.grade, 5 };
    

Utilizzare LINQ

È possibile creare una query LINQ con GetItemLinqQueryable. Questo esempio mostra la generazione di query LINQ e l'esecuzione asincrona con un 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);
    }
}

Operatori LINQ supportati

Il provider LINQ incluso in NoSQL .NET SDK supporta gli operatori seguenti:

  • Select: le proiezioni convertono in SELECT, inclusa la costruzione dell'oggetto.
  • Dove: i filtri vengono convertiti in WHERE e supportano la conversione tra &&gli operatori , ||e ! negli operatori NoSQL
  • SelectMany: consente la rimozione di matrici nella clausola JOIN. Utilizzare per concatenare o annidare le espressioni per filtrare in base agli elementi della matrice.
  • OrderBy e OrderByDescending: tradurre in ORDER BY con ASC o DESC.
  • Operatori di aggregazione Count, Sum, Min, Max e Average e relativi equivalenti asincroni CountAsync, SumAsync, MinAsync, MaxAsync e AverageAsync.
  • CompareTo: converte in confronti di intervallo. Questo operatore viene comunemente usato per le stringhe, poiché non sono confrontabili in .NET.
  • Skip e Take: converte in OFFSET e LIMIT per limitare i risultati di una query ed effettuare la paginazione.
  • Funzioni matematiche: supporta la conversione da .NET Abs, Acos, Asin, Atan, Ceiling,Cos, Exp, Floor, Log, Log10, Pow, Round, Sign, Sin,Sqrt, Tan e Truncate alle funzioni matematiche predefinite equivalenti.
  • Funzioni stringa: supporta la conversione da .NET Concat, Contains, Count, EndsWith,IndexOf, Replace, Reverse, StartsWith, SubString, ToLower, ToUpper, TrimEnd, e TrimStart alle funzioni stringa predefinite equivalenti.
  • Funzioni di matrice: supporta la conversione da .NET Concat, Contains e Count alle funzioni di matrice predefinite equivalenti.
  • Funzioni di estensione geospaziale: supporta la conversione dai metodi stub Distance, IsValid, IsValidDetailed e Within alle funzioni geospaziali predefinite equivalenti.
  • Funzione di estensione della funzione definita dall'utente: supporta la conversione dal metodo stub CosmosLinq.InvokeUserDefinedFunction alla funzione definita dall'utente corrispondente.
  • Miscellaneous: supporta la conversione di Coalesce e di operatori condizionali. Può eseguire la conversione di Contains in String CONTAINS, ARRAY_CONTAINS o IN, a seconda del contesto.

Esempi

Gli esempi seguenti illustrano come alcuni degli operatori di query LINQ standard convertono in query in Azure Cosmos DB.

Selezionare l'operatore

La sintassi è input.Select(x => f(x)), dove f è un'espressione scalare. In questo caso, input sarebbe un oggetto IQueryable.

Operatore Select, esempio 1:

  • Espressione lambda LINQ

    input.Select(family => family.parents[0].familyName);
    
  • NoSQL

    SELECT VALUE f.parents[0].familyName
    FROM Families f
    

Operatore Select, esempio 2:

  • Espressione lambda 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
    

Operatore Select, esempio 3:

  • Espressione lambda 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
    

Operatore SelectMany

La sintassi è input.SelectMany(x => f(x)), dove f è un'espressione scalare che restituisce un tipo di contenitore.

  • Espressione lambda LINQ

    input.SelectMany(family => family.children);
    
  • NoSQL

    SELECT VALUE child
    FROM child IN Families.children
    

Operatore Where

La sintassi è input.Where(x => f(x)), dove f è un'espressione scalare che restituisce un valore booleano.

Operatore Where, esempio 1:

  • Espressione lambda LINQ

    input.Where(family=> family.parents[0].familyName == "Wakefield");
    
  • NoSQL

    SELECT *
    FROM Families f
    WHERE f.parents[0].familyName = "Wakefield"
    

Operatore Where, esempio 2:

  • Espressione lambda 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
    

Query NoSQL composite

È possibile comporre gli operatori precedenti per formare query più potenti. Poiché Azure Cosmos DB supporta contenitori annidati, è possibile concatenare o annidare la composizione.

Concatenation

La sintassi è input(.|.SelectMany())(.Select()|.Where())*. Una query concatenata può iniziare con una query facoltativa SelectMany, seguita da più operatori Select o Where.

Concatenazione, esempio 1:

  • Espressione lambda LINQ

    input.Select(family => family.parents[0])
        .Where(parent => parent.familyName == "Wakefield");
    
  • NoSQL

    SELECT *
    FROM Families f
    WHERE f.parents[0].familyName = "Wakefield"
    

Concatenazione, esempio 2:

  • Espressione lambda 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
    

Concatenazione, esempio 3:

  • Espressione lambda 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)
    

Concatenazione, esempio 4:

  • Espressione lambda LINQ

    input.SelectMany(family => family.parents)
        .Where(parent => parents.familyName == "Wakefield");
    
  • NoSQL

    SELECT *
    FROM p IN Families.parents
    WHERE p.familyName = "Wakefield"
    

Annidamento

La sintassi è input.SelectMany(x=>x.Q()) laddove Q è un operatore Select, SelectMany o Where.

Una query annidata applica la query più interna a ogni elemento del contenitore esterno. Una funzionalità importante è che la query interna può riferirsi ai campi degli elementi nel contenitore esterno come un self-join.

Annidamento, esempio 1:

  • Espressione lambda LINQ

    input.SelectMany(family=>
        family.parents.Select(p => p.familyName));
    
  • NoSQL

    SELECT VALUE p.familyName
    FROM Families f
    JOIN p IN f.parents
    

Annidamento, esempio 2:

  • Espressione lambda 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"
    

Annidamento, esempio 3:

  • Espressione lambda 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