Tłumaczenie LINQ to NoSQL w usłudze Azure Cosmos DB for NoSQL

DOTYCZY: NoSQL

Dostawca zapytań usługi Azure Cosmos DB wykonuje najlepsze mapowanie na podstawie zapytania LINQ do zapytania Usługi Azure Cosmos DB for NoSQL. Jeśli chcesz uzyskać zapytanie NoSQL przetłumaczone z LINQ, użyj ToString() metody na wygenerowanym IQueryable obiekcie. W poniższym opisie przyjęto założenie, że podstawowa znajomość linQ. Oprócz LINQ usługa Azure Cosmos DB obsługuje również platformę Entity Framework Core, która współpracuje z interfejsem API dla noSQL.

Uwaga

Zalecamy używanie najnowszej wersji zestawu .NET SDK (Microsoft.Azure.Cosmos)

System typów dostawcy zapytań obsługuje tylko typy pierwotne JSON: numeric, Boolean, stringi null.

Dostawca zapytań obsługuje następujące wyrażenia skalarne:

  • Stałe wartości, w tym stałe wartości pierwotnych typów danych w czasie oceny zapytania.

  • Wyrażenia indeksu właściwości/tablicy odwołujące się do właściwości obiektu lub elementu tablicy. Na przykład:

    family.Id;
    family.children[0].familyName;
    family.children[0].grade;
    
    int n = 1;
    
    family.children[n].grade;
    
  • Wyrażenia arytmetyczne, w tym typowe wyrażenia arytmetyczne dla wartości liczbowych i logicznych.

    2 * family.children[0].grade;
    x + y;
    
  • Wyrażenia porównania ciągów, które obejmują porównanie wartości ciągu z wartością ciągu stałej.

    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);
    
  • Wyrażenia tworzenia obiektu/tablicy, które zwracają obiekt typu wartości złożonej lub typu anonimowego albo tablicę takich obiektów. Te wartości można zagnieżdżać.

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

Korzystanie z LINQ

Zapytanie LINQ można utworzyć za pomocą polecenia GetItemLinqQueryable. W tym przykładzie pokazano generowanie zapytań LINQ i wykonywanie asynchroniczne z elementem 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);
    }
}

Obsługiwane operatory LINQ

Dostawca LINQ dołączony do zestawu .NET SDK NoSQL obsługuje następujące operatory:

  • Wybierz: projekcje przekładają się na select, w tym konstrukcję obiektów.
  • Gdzie: filtry tłumaczą się na where i obsługują tłumaczenie między operatorami &&, ||i ! noSQL
  • SelectMany: umożliwia odwijanie tablic do klauzuli JOIN . Służy do tworzenia łańcuchów lub zagnieżdżania wyrażeń do filtrowania elementów tablicy.
  • OrderBy i OrderByDescending: Translate to ORDER BY with ASC or DESC (Tłumaczenie na order by za pomocą usługi ASC lub DESC).
  • Operatory Count, Sum, Min, Max i Average na potrzeby agregacji oraz ich asynchroniczne odpowiedniki CountAsync, SumAsync, MinAsync, MaxAsync i AverageAsync.
  • CompareTo: operator tłumaczony na porównania zakresu. Ten operator jest często używany w przypadku ciągów, ponieważ nie są one porównywalne na platformie .NET.
  • Pomiń i przejmij: przekłada się na przesunięcie i limit , aby ograniczyć wyniki z zapytania i wykonywać stronicowanie.
  • Funkcje matematyczne: obsługuje tłumaczenie z platformy .NETAbs, CeilingSinAtanCosAsinExpAcosFloorLogSignTanRoundPowSqrtLog10i Truncate na równoważne wbudowane funkcje matematyczne.
  • Funkcje ciągów: obsługuje tłumaczenie z funkcji ciągów .NETConcat, , ReverseCountContainsEndsWithIndexOfToLowerTrimEndSubStringStartsWithToUpperReplace, i TrimStart na równoważne wbudowane funkcje ciągów.
  • Funkcje tablicy: obsługuje tłumaczenie z platformy .NET Concat, Containsi Count na równoważne wbudowane funkcje tablicy.
  • Funkcje rozszerzenia geoprzestrzennego: obsługuje tłumaczenie z metod wycinków Distance, IsValid, IsValidDetailedi Within do równoważnych wbudowanych funkcji geoprzestrzennych.
  • Funkcja rozszerzenia funkcji zdefiniowanej przez użytkownika: obsługuje tłumaczenie z metody wycinka CosmosLinq.InvokeUserDefinedFunction do odpowiedniej funkcji zdefiniowanej przez użytkownika.
  • Różne: obsługuje tłumaczenie operatorów warunkowychCoalesce i . W zależności od kontekstu można przetłumaczyć Contains na ciąg CONTAINS, ARRAY_CONTAINS lub IN.

Przykłady

W poniższych przykładach pokazano, jak niektóre standardowe operatory zapytań LINQ tłumaczą się na zapytania w usłudze Azure Cosmos DB.

Operator Select

Składnia to input.Select(x => f(x)), gdzie f jest wyrażeniem skalarnym. Element input, w tym przypadku będzie obiektem IQueryable .

Wybierz operator, przykład 1:

  • Wyrażenie lambda składni LINQ

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

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

Wybierz operator, przykład 2:

  • Wyrażenie lambda składni 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
    

Wybierz operator, przykład 3:

  • Wyrażenie lambda składni 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
    

Operator SelectMany

Składnia to input.SelectMany(x => f(x)), gdzie f jest wyrażeniem skalarnym, które zwraca typ kontenera.

  • Wyrażenie lambda składni LINQ

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

    SELECT VALUE child
    FROM child IN Families.children
    

Operator Where

Składnia to input.Where(x => f(x)), gdzie f jest wyrażenie skalarnym, które zwraca wartość logiczną.

Gdzie operator, przykład 1:

  • Wyrażenie lambda składni LINQ

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

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

Gdzie operator, przykład 2:

  • Wyrażenie lambda składni 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
    

Złożone zapytania NoSQL

Powyższe operatory można tworzyć w celu utworzenia bardziej zaawansowanych zapytań. Ponieważ usługa Azure Cosmos DB obsługuje zagnieżdżone kontenery, możesz połączyć lub zagnieżdżać kompozycję.

Łączenie

Składnia jest następująca: input(.|.SelectMany())(.Select()|.Where())* Zapytanie łączone może rozpoczynać się od opcjonalnego SelectMany zapytania, po którym następuje wiele Select operatorów lub Where .

Łączenie, przykład 1:

  • Wyrażenie lambda składni LINQ

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

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

Łączenie, przykład 2:

  • Wyrażenie lambda składni 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
    

Łączenie, przykład 3:

  • Wyrażenie lambda składni 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)
    

Łączenie, przykład 4:

  • Wyrażenie lambda składni LINQ

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

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

Zagnieżdżanie

Składnia to input.SelectMany(x=>x.Q()) gdzie Q jest operatorem Select, SelectManylub Where .

Zapytanie zagnieżdżone stosuje zapytanie wewnętrzne do każdego elementu kontenera zewnętrznego. Jedną z ważnych funkcji jest to, że zapytanie wewnętrzne może odwoływać się do pól elementów w kontenerze zewnętrznym, takich jak samosprzężenie.

Zagnieżdżanie, przykład 1:

  • Wyrażenie lambda składni LINQ

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

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

Zagnieżdżanie, przykład 2:

  • Wyrażenie lambda składni 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"
    

Zagnieżdżanie, przykład 3:

  • Wyrażenie lambda składni 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