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
, Boolean
string
, 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
eTruncate
alle funzioni matematiche predefinite equivalenti. - Funzioni stringa: supporta la conversione da .NET
Concat
,Contains
,Count
,EndsWith
,IndexOf
,Replace
,Reverse
,StartsWith
,SubString
,ToLower
,ToUpper
,TrimEnd
, eTrimStart
alle funzioni stringa predefinite equivalenti. - Funzioni di matrice: supporta la conversione da .NET
Concat
,Contains
eCount
alle funzioni di matrice predefinite equivalenti. - Funzioni di estensione geospaziale: supporta la conversione dai metodi stub
Distance
,IsValid
,IsValidDetailed
eWithin
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 diContains
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