適用於 NoSQL 的 Azure Cosmos DB 中的 LINQ to NoSQL 翻譯
適用於:NoSQL
Azure Cosmos DB 查詢提供者會執行從 LINQ 查詢到適用於 NoSQL 查詢的 Azure Cosmos DB 的最佳對應。 如果您想要取得從 LINQ 轉譯的 NoSQL 查詢,請在 ToString()
產生的 IQueryable
物件上使用 方法。 下列說明假設您已對 LINQ 有基本的熟悉度。 除了 LINQ,Azure Cosmos DB 也支援 Entity Framework Core,其適用於 NoSQL 的 API。
注意
我們建議使用最新的 .NET SDK (Microsoft.Azure.Cosmos
) 版本
查詢提供者類型系統僅支援 JSON 基本類型: numeric
、 Boolean
、 string
和 null
。
查詢提供者支援下列純量運算式:
常數值,包括查詢評估時間的基本資料類型常數值。
屬性/陣列索引運算式,參照物件或陣列項目的屬性。 例如:
family.Id; family.children[0].familyName; family.children[0].grade;
int n = 1; family.children[n].grade;
算術運算式,包括數值和布林值的一般算術運算式。
2 * family.children[0].grade; x + y;
字串比較運算式,包括比較字串值與某個常數字串值。
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);
物件/陣列建立運算式,傳回複合值類型或匿名類型的物件,或是這類物件的陣列。 您可以將這些值巢狀化。
new Parent { familyName = "Wakefield", givenName = "Robin" }; new { first = 1, second = 2 }; //an anonymous type with two fields new int[] { 3, child.grade, 5 };
使用 LINQ
您可以使用 GetItemLinqQueryable
建立 LINQ 查詢。 此範例展示使用 FeedIterator
進行 LINQ 查詢產生和非同步執行:
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);
}
}
支援的 LINQ 運算子
NoSQL .NET SDK 隨附的 LINQ 提供者支援下列運算符:
- Select:投影會轉譯為 SELECT,包括物件建構。
- 其中:篩選會轉譯為 WHERE,並支援 、
||
和!
之間的&&
轉譯至 NoSQL 運算符 - SelectMany:可讓陣列回溯到 SQL JOIN 子句。 用於鏈結或嵌套運算式來篩選陣列元素。
- OrderBy 和 OrderByDescending:使用 ASC 或 DESC 轉譯為 ORDER BY。
- 匯總的 Count、Sum、Min、Max 和 Average 運算符,以及其異步對等專案 CountAsync、SumAsync、MinAsync、MaxAsync 和 AverageAsync。
- CompareTo:轉譯為範圍比較。 此運算子通常用於字串,因為它們在 .NET 中無法比較。
- Skip 和 Take:轉譯為 OFFSET 和 LIMIT 以限制查詢的結果並進行分頁。
- 數學函數:支援從 .NET
Abs
、Acos
、Asin
、Atan
、Ceiling
、Cos
、Exp
、Floor
、Log
、Log10
、Pow
、Round
、Sign
、Sin
、Sqrt
、Tan
和Truncate
轉譯為對等的內建數學函數。 - 字串函數:支援從 .NET
Concat
、Contains
、Count
、EndsWith
、IndexOf
、Replace
、Reverse
、StartsWith
、SubString
、ToLower
、ToUpper
、TrimEnd
和TrimStart
轉譯為對等的內建字串函數。 - 陣列函數:支援從 .NET
Concat
、Contains
和Count
轉譯為對等的內建陣列函數。 - 地理空間擴充函數:支援從虛設常式方法
Distance
、IsValid
、IsValidDetailed
和Within
轉譯為對等的內建地理空間函數。 - 用戶定義函式擴充函式:支援從存根方法 CosmosLinq.InvokeUserDefinedFunction 轉譯至對應的使用者定義函式。
- 其他:支援
Coalesce
和條件式運算子的轉譯。 可根據內容將Contains
轉譯為字串 CONTAINS、ARRAY_CONTAINS 或 IN。
範例
下列範例說明一些標準 LINQ 查詢運算子如何轉譯成 Azure Cosmos DB 中的查詢。
選取運算子
語法為 input.Select(x => f(x))
,其中 f
是純量運算式。 input
在此案例中會是 IQueryable
物件。
Select 運算子,範例 1:
LINQ Lambda 運算式
input.Select(family => family.parents[0].familyName);
NoSQL
SELECT VALUE f.parents[0].familyName FROM Families f
Select 運算子,範例 2:
LINQ Lambda 運算式
input.Select(family => family.children[0].grade + c); // c is an int variable
NoSQL
SELECT VALUE f.children[0].grade + c FROM Families f
Select 運算子,範例 3:
LINQ Lambda 運算式
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
SelectMany 運算子
語法為 input.SelectMany(x => f(x))
,其中 f
是傳回容器類型的純量運算式。
LINQ Lambda 運算式
input.SelectMany(family => family.children);
NoSQL
SELECT VALUE child FROM child IN Families.children
Where 運算子
語法為 input.Where(x => f(x))
,其中 f
是傳回布林值的純量運算式。
Where 運算子,範例 1:
LINQ Lambda 運算式
input.Where(family=> family.parents[0].familyName == "Wakefield");
NoSQL
SELECT * FROM Families f WHERE f.parents[0].familyName = "Wakefield"
Where 運算子,範例 2:
LINQ Lambda 運算式
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
複合 NoSQL 查詢
您可以撰寫上述運算子以建立功能更強大的查詢。 由於 Azure Cosmos DB 支援巢狀容器,因此您可以串連或巢狀組合。
串連
語法是 input(.|.SelectMany())(.Select()|.Where())*
。 串連查詢的開頭可以是選用的 SelectMany
查詢,其後接著多個 Select
或 Where
運算子。
串連,範例 1:
LINQ Lambda 運算式
input.Select(family => family.parents[0]) .Where(parent => parent.familyName == "Wakefield");
NoSQL
SELECT * FROM Families f WHERE f.parents[0].familyName = "Wakefield"
串連,範例 2:
LINQ Lambda 運算式
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
串連,範例 3:
LINQ Lambda 運算式
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)
串連,範例 4:
LINQ Lambda 運算式
input.SelectMany(family => family.parents) .Where(parent => parents.familyName == "Wakefield");
NoSQL
SELECT * FROM p IN Families.parents WHERE p.familyName = "Wakefield"
巢狀
語法為 input.SelectMany(x=>x.Q())
,其中 Q
是 Select
、SelectMany
或 Where
運算子。
巢狀查詢會將內部查詢套用至外部容器的每個項目。 其中一個重要功能是內部查詢可以參照外部容器中項目的欄位,例如自我聯結。
巢狀,範例 1:
LINQ Lambda 運算式
input.SelectMany(family=> family.parents.Select(p => p.familyName));
NoSQL
SELECT VALUE p.familyName FROM Families f JOIN p IN f.parents
巢狀,範例 2:
LINQ Lambda 運算式
input.SelectMany(family => family.children.Where(child => child.familyName == "Jeff"));
NoSQL
SELECT * FROM Families f JOIN c IN f.children WHERE c.familyName = "Jeff"
巢狀,範例 3:
LINQ Lambda 運算式
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