LINQ naar NoSQL-vertaling in Azure Cosmos DB for NoSQL
VAN TOEPASSING OP: NoSQL
De Azure Cosmos DB-queryprovider voert een best effort-toewijzing uit van een LINQ-query naar een Azure Cosmos DB for NoSQL-query. Als u de NoSQL-query wilt ophalen die wordt vertaald vanuit LINQ, gebruikt u de ToString()
methode voor het gegenereerde IQueryable
object. In de volgende beschrijving wordt ervan uitgegaan dat u bekend bent met LINQ. Naast LINQ biedt Azure Cosmos DB ook ondersteuning voor Entity Framework Core, dat werkt met API voor NoSQL.
Notitie
U wordt aangeraden de nieuwste versie van de .NET SDK (Microsoft.Azure.Cosmos
) te gebruiken
Het typesysteem van de queryprovider ondersteunt alleen de primitieve JSON-typen: numeric
, Boolean
, string
en null
.
De queryprovider ondersteunt de volgende scalaire expressies:
Constante waarden, inclusief constante waarden van de primitieve gegevenstypen tijdens de query-evaluatietijd.
Eigenschaps-/matrixindexexpressies die verwijzen naar de eigenschap van een object of een matrixelement. Voorbeeld:
family.Id; family.children[0].familyName; family.children[0].grade;
int n = 1; family.children[n].grade;
Rekenkundige expressies, waaronder algemene rekenkundige expressies voor numerieke en Booleaanse waarden.
2 * family.children[0].grade; x + y;
Vergelijkingsexpressies voor tekenreeksen, waaronder het vergelijken van een tekenreekswaarde met een constante tekenreekswaarde.
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);
Expressies voor het maken van objecten/matrices, die een object retourneren van het samengestelde waardetype of anoniem type, of een matrix van dergelijke objecten. U kunt deze waarden nesten.
new Parent { familyName = "Wakefield", givenName = "Robin" }; new { first = 1, second = 2 }; //an anonymous type with two fields new int[] { 3, child.grade, 5 };
LINQ gebruiken
U kunt een LINQ-query maken met GetItemLinqQueryable
. In dit voorbeeld ziet u het genereren van LINQ-query's en asynchrone uitvoering met een 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);
}
}
Ondersteunde LINQ-operators
De LINQ-provider die is opgenomen in de NoSQL .NET SDK ondersteunt de volgende operators:
- Select: Projecties worden omgezet in SELECT, inclusief objectconstructie.
- Waar: Filters vertalen naar WHERE en ondersteunen vertaling tussen
&&
,||
en!
naar de NoSQL-operators - SelectMany: Maakt het mogelijk om matrices af te sluiten op de JOIN-component . Hiermee kunt u expressies koppelen of nesten om te filteren op matrixelementen.
- OrderBy en OrderByDescending: Vertalen naar ORDER BY met ASC of DESC.
- Operatoren Count, Sum, Min, Max en Average voor statistische functies en de bijbehorende asynchrone equivalenten CountAsync, SumAsync, MinAsync, MaxAsync en AverageAsync.
- CompareTo: wordt omgezet naar bereikvergelijkingen. Deze operator wordt vaak gebruikt voor tekenreeksen, omdat ze niet vergelijkbaar zijn in .NET.
- Overslaan en nemen: wordt omgezet in OFFSET en LIMIT voor het beperken van resultaten van een query en het uitvoeren van paginering.
- Wiskundige functies: ondersteunt vertaling van .NET
Abs
,Acos
,Asin
Atan
, ,Ceiling
Cos
,Log
Floor
Log10
Sign
Sin
Pow
Exp
Round
,Sqrt
enTruncate
Tan
naar de equivalente ingebouwde wiskundige functies. - Tekenreeksfuncties: ondersteunt vertaling van .NET
Concat
,Contains
,Count
,EndsWith
, ,Replace
IndexOf
,Reverse
,SubString
StartsWith
ToLower
ToUpper
enTrimStart
TrimEnd
tot de equivalente ingebouwde tekenreeksfuncties. - Matrixfuncties: ondersteunt vertaling van .NET
Concat
Contains
enCount
de equivalente ingebouwde matrixfuncties. - Georuimtelijke extensiefuncties: ondersteunt vertaling van stub-methoden
Distance
,IsValid
IsValidDetailed
enWithin
de equivalente ingebouwde georuimtelijke functies. - Door de gebruiker gedefinieerde functieextensiefunctie: ondersteunt vertaling van de stub-methode CosmosLinq.InvokeUserDefinedFunction naar de bijbehorende door de gebruiker gedefinieerde functie.
- Diversen: ondersteunt de vertaling van
Coalesce
en voorwaardelijke operators. Kan worden vertaaldContains
naar STRING CONTAINS, ARRAY_CONTAINS of IN, afhankelijk van de context.
Voorbeelden
In de volgende voorbeelden ziet u hoe sommige standaard LINQ-queryoperators worden omgezet in query's in Azure Cosmos DB.
Operator selecteren
De syntaxis is input.Select(x => f(x))
. Hierbij is f
een scalaire expressie. In input
dit geval zou het een IQueryable
object zijn.
Operator selecteren, voorbeeld 1:
LINQ lambda-expressie
input.Select(family => family.parents[0].familyName);
NoSQL
SELECT VALUE f.parents[0].familyName FROM Families f
Operator selecteren, voorbeeld 2:
LINQ lambda-expressie
input.Select(family => family.children[0].grade + c); // c is an int variable
NoSQL
SELECT VALUE f.children[0].grade + c FROM Families f
Operator selecteren, voorbeeld 3:
LINQ lambda-expressie
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
Operator SelectMany
De syntaxis is input.SelectMany(x => f(x))
. Hierbij is f
een scalaire expressie die een containertype retourneert.
LINQ lambda-expressie
input.SelectMany(family => family.children);
NoSQL
SELECT VALUE child FROM child IN Families.children
Operator Where
De syntaxis is input.Where(x => f(x))
. Hierbij is f
een scalaire expressie die een Booleaanse waarde retourneert.
Where-operator, voorbeeld 1:
LINQ lambda-expressie
input.Where(family=> family.parents[0].familyName == "Wakefield");
NoSQL
SELECT * FROM Families f WHERE f.parents[0].familyName = "Wakefield"
Where-operator, voorbeeld 2:
LINQ lambda-expressie
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
Samengestelde NoSQL-query's
U kunt de voorgaande operators opstellen om krachtigere query's te maken. Omdat Azure Cosmos DB geneste containers ondersteunt, kunt u de samenstelling samenvoegen of nesten.
Samenvoegen
De syntaxis is input(.|.SelectMany())(.Select()|.Where())*
. Een samengevoegde query kan beginnen met een optionele SelectMany
query, gevolgd door meerdere Select
of Where
operators.
Samenvoeging, voorbeeld 1:
LINQ lambda-expressie
input.Select(family => family.parents[0]) .Where(parent => parent.familyName == "Wakefield");
NoSQL
SELECT * FROM Families f WHERE f.parents[0].familyName = "Wakefield"
Samenvoeging, voorbeeld 2:
LINQ lambda-expressie
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
Samenvoeging, voorbeeld 3:
LINQ lambda-expressie
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)
Samenvoeging, voorbeeld 4:
LINQ lambda-expressie
input.SelectMany(family => family.parents) .Where(parent => parents.familyName == "Wakefield");
NoSQL
SELECT * FROM p IN Families.parents WHERE p.familyName = "Wakefield"
Nesten
De syntaxis is waar Q
een Select
, SelectMany
of Where
operator isinput.SelectMany(x=>x.Q())
.
Met een geneste query wordt de binnenste query toegepast op elk element van de buitenste container. Een belangrijke functie is dat de binnenste query kan verwijzen naar de velden van de elementen in de buitenste container, zoals een self-join.
Nesten, voorbeeld 1:
LINQ lambda-expressie
input.SelectMany(family=> family.parents.Select(p => p.familyName));
NoSQL
SELECT VALUE p.familyName FROM Families f JOIN p IN f.parents
Nesten, voorbeeld 2:
LINQ lambda-expressie
input.SelectMany(family => family.children.Where(child => child.familyName == "Jeff"));
NoSQL
SELECT * FROM Families f JOIN c IN f.children WHERE c.familyName = "Jeff"
Nesten, voorbeeld 3:
LINQ lambda-expressie
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