다음을 통해 공유


LINQ 번역 - Cosmos DB의 쿼리 언어(Azure 및 패브릭)

Cosmos DB(Azure 및 패브릭) 쿼리 공급자는 효율적인 데이터 검색을 위해 LINQ(언어 통합 쿼리)를 NoSQL 쿼리로 변환합니다. 이 문서에서는 지원되는 LINQ 연산자와 LINQ 쿼리가 Cosmos DB 구문에 매핑되어 .NET 개발자가 데이터베이스 쿼리를 최적화하는 데 도움이 되는 방법을 설명합니다. LINQ 코드에서 번역된 NoSQL 쿼리를 보려면 생성된 IQueryable 개체의 ToString() 메서드를 사용합니다. 다음 설명에서는 LINQ에 대한 기본적인 지식이 있다고 가정합니다. LinQ 외에도 Cosmos DB는 NoSQL용 API와 함께 작동하는 Entity Framework Core도 지원합니다.

비고

최신 .NET SDK(Microsoft.Azure.Cosmos) 버전을 사용하는 것이 좋습니다.

쿼리 공급자 형식 시스템은 JSON 기본 형식 numeric인 , Boolean, stringnull.

쿼리 공급자는 다음 스칼라 식을 지원합니다.

  • 쿼리 평가 시 기본 데이터 형식의 상수 값을 포함한 상수 값입니다.

  • 개체 또는 배열 요소의 속성을 참조하는 속성/배열 인덱스 식입니다. 다음은 그 예입니다.

    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 사용

를 사용하여 LINQ 쿼리 GetItemLinqQueryable를 만들 수 있습니다. 이 예제에서는 다음을 사용하여 LINQ 쿼리 생성 및 비동기 실행을 보여 줍니다.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);
    }
}

지원되는 LINQ 연산자

NoSQL .NET SDK에 포함된 LINQ 공급자는 다음 연산자를 지원합니다.

  • 선택: 개체 생성을 포함하여 프로젝션이 SELECT변환됩니다.
  • 위치: 필터가 변환되고 WHERE, ||! 및 NoSQL 연산자 간 &&변환을 지원합니다.
  • SelectMany: 절에 대한 배열 해제를 JOIN 허용합니다. 배열 요소를 필터링하기 위해 식을 연결하거나 중첩하는 데 사용합니다.
  • OrderByOrderByDescending: 와 함께 또는 DESC.ASCORDER BY 변환
  • 집계에 대한 Count, Sum, Min, MaxAverage 연산자 및 해당 비동기 연산자는 CountAsync, SumAsync, MinAsync, MaxAsyncAverageAsync에 해당합니다.
  • CompareTo: 범위 비교로 변환합니다. 이 연산자는 .NET에서 비교할 수 없으므로 문자열에 일반적으로 사용됩니다.
  • 건너뛰기 및 사용: 쿼리의 결과를 제한하고 LIMIT페이지 매김을 수행하도록 변환OFFSET합니다.
  • 수학 함수: .NETAbs, , Acos, , Asin, Atan, Ceiling, CosFloorLogExp, Log10, , Pow, TanSinSignSqrtRoundTruncate 동등한 기본 제공 수학 함수로의 번역을 지원합니다.
  • 문자열 함수: .NETConcat, , , Contains, Count,IndexOfEndsWithReplaceToLowerTrimEndSubStringStartsWithToUpperReverseTrimStart 해당하는 기본 제공 문자열 함수로의 변환을 지원합니다.
  • 배열 함수: .NET ConcatContainsCount 에서 동일한 기본 제공 배열 함수로의 변환을 지원합니다.
  • 지리 공간적 확장 함수: 스텁 메서드DistanceIsValidIsValidDetailed, 및 Within 해당하는 기본 제공 지리 공간적 함수로의 변환을 지원합니다.
  • User-Defined 함수 확장 함수: 스텁 메서드 CosmosLinq.InvokeUserDefinedFunction 에서 해당 사용자 정의 함수로의 변환을 지원합니다.
  • 기타: 조건부 연산자의 Coalesce 변환을 지원합니다. 컨텍스트에 따라 문자열 CONTAINS또는 ARRAY_CONTAINSIN문자열로 변환 Contains 할 수 있습니다.

예시

다음 예제에서는 일부 표준 LINQ 쿼리 연산자가 Cosmos DB의 쿼리로 변환되는 방법을 보여 줍니다.

연산자 선택

구문은 input.Select(x => f(x))f 스칼라 식입니다. 이 input경우 개체가 IQueryable 됩니다.

Select 연산자, 예제 1:

  • LINQ 람다 식

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

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

Select 연산자, 예제 2:

  • 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
    

Select 연산자, 예제 3:

  • 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
    

SelectMany 연산자

구문은 input.SelectMany(x => f(x))f 컨테이너 형식을 반환하는 스칼라 식입니다.

  • LINQ 람다 식

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

    SELECT VALUE child
    FROM child IN Families.children
    

Where 연산자

구문은 input.Where(x => f(x))f 부울 값을 반환하는 스칼라 식입니다.

Where 연산자, 예제 1:

  • LINQ 람다 식

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

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

Where 연산자, 예제 2:

  • 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
    

복합 NoSQL 쿼리

이전 연산자를 작성하여 더 강력한 쿼리를 구성할 수 있습니다. Cosmos DB는 중첩된 컨테이너를 지원하므로 컴퍼지션을 연결하거나 중첩할 수 있습니다.

연결

구문은 input(.|.SelectMany())(.Select()|.Where())*입니다. 연결된 쿼리는 선택적 SelectMany 쿼리로 시작하고 그 뒤에 여러 Select 개 또는 Where 연산자가 올 수 있습니다.

연결, 예제 1:

  • LINQ 람다 식

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

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

연결, 예제 2:

  • 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
    

연결, 예제 3:

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

연결, 예제 4:

  • LINQ 람다 식

    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 , SelectMany또는 Where 연산자입니다Select.

중첩된 쿼리는 외부 컨테이너의 각 요소에 내부 쿼리를 적용합니다. 한 가지 중요한 기능은 내부 쿼리가 자체 조인과 같이 외부 컨테이너의 요소 필드를 참조할 수 있다는 것입니다.

중첩, 예제 1:

  • LINQ 람다 식

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

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

중첩, 예제 2:

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

중첩, 예제 3:

  • 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