Учебники

DocumentDB SQL — перевод с Linq на SQL

В DocumentDB мы фактически используем SQL для запроса документов. Если мы занимаемся разработкой .NET, есть также поставщик LINQ, который можно использовать и который может генерировать соответствующий SQL из запроса LINQ.

Поддерживаемые типы данных

В DocumentDB все типы примитивов JSON поддерживаются в поставщике LINQ, включенном в DocumentDB .NET SDK, а именно:

  • числовой
  • логический
  • строка
  • Ноль

Поддерживаемое выражение

Следующие скалярные выражения поддерживаются в поставщике LINQ, входящем в состав DocumentDB .NET SDK.

  • Постоянные значения — включает постоянные значения примитивных типов данных.

  • Выражения свойства / индекса массива — выражения относятся к свойству объекта или элемента массива.

  • Арифметические выражения — включает в себя общие арифметические выражения для числовых и логических значений.

  • Выражение сравнения строк — включает сравнение строкового значения с некоторым постоянным строковым значением.

  • Выражение создания объекта / массива — возвращает объект составного типа значения или анонимного типа или массив таких объектов. Эти значения могут быть вложенными.

Постоянные значения — включает постоянные значения примитивных типов данных.

Выражения свойства / индекса массива — выражения относятся к свойству объекта или элемента массива.

Арифметические выражения — включает в себя общие арифметические выражения для числовых и логических значений.

Выражение сравнения строк — включает сравнение строкового значения с некоторым постоянным строковым значением.

Выражение создания объекта / массива — возвращает объект составного типа значения или анонимного типа или массив таких объектов. Эти значения могут быть вложенными.

Поддерживаемые операторы LINQ

Вот список поддерживаемых операторов LINQ в поставщике LINQ, включенном в DocumentDB .NET SDK.

  • Select — Проекции переводятся в SQL SELECT, включая конструкцию объекта.

  • Где — Фильтры переводят в SQL WHERE и поддерживают перевод между &&, || а также ! к операторам SQL.

  • SelectMany — позволяет разматывать массивы в предложение SQL JOIN. Может использоваться для цепочки / вложенных выражений для фильтрации элементов массива.

  • OrderBy и OrderByDescending — переводит в ORDER BY по возрастанию / убыванию.

  • CompareTo — переводит в диапазон сравнения. Обычно используется для строк, поскольку они не сопоставимы в .NET.

  • Take — переводит в SQL TOP для ограничения результатов запроса.

  • Математические функции — Поддерживает перевод из .NET Abs, Acos, Asin, Atan, Ceiling, Cos, Exp, Floor, Log, Log10, Pow, Round, Sign, Sin, Sqrt, Tan, Truncate в эквивалентные встроенные функции SQL.

  • Строковые функции — поддерживает перевод из .NET Concat, Contains, EndsWith, IndexOf, Count, ToLower, TrimStart, Replace, Reverse, TrimEnd, StartsWith, SubString, ToUpper в эквивалентные встроенные функции SQL.

  • Функции массива — поддерживает перевод из .NET Concat, Contains и Count в эквивалентные встроенные функции SQL.

  • Функции расширения геопространственных данных — Поддерживает перевод из методов-заглушек Distance, Within, IsValid и IsValidDetailed в эквивалентные встроенные функции SQL.

  • Определяемая пользователем функция расширения — Поддерживает перевод из метода-заглушки UserDefinedFunctionProvider.Invoke в соответствующую пользовательскую функцию.

  • Разное — Поддерживает перевод объединенных и условных операторов. Может переводить Contains в String CONTAINS, ARRAY_CONTAINS или SQL IN в зависимости от контекста.

Select — Проекции переводятся в SQL SELECT, включая конструкцию объекта.

Где — Фильтры переводят в SQL WHERE и поддерживают перевод между &&, || а также ! к операторам SQL.

SelectMany — позволяет разматывать массивы в предложение SQL JOIN. Может использоваться для цепочки / вложенных выражений для фильтрации элементов массива.

OrderBy и OrderByDescending — переводит в ORDER BY по возрастанию / убыванию.

CompareTo — переводит в диапазон сравнения. Обычно используется для строк, поскольку они не сопоставимы в .NET.

Take — переводит в SQL TOP для ограничения результатов запроса.

Математические функции — Поддерживает перевод из .NET Abs, Acos, Asin, Atan, Ceiling, Cos, Exp, Floor, Log, Log10, Pow, Round, Sign, Sin, Sqrt, Tan, Truncate в эквивалентные встроенные функции SQL.

Строковые функции — поддерживает перевод из .NET Concat, Contains, EndsWith, IndexOf, Count, ToLower, TrimStart, Replace, Reverse, TrimEnd, StartsWith, SubString, ToUpper в эквивалентные встроенные функции SQL.

Функции массива — поддерживает перевод из .NET Concat, Contains и Count в эквивалентные встроенные функции SQL.

Функции расширения геопространственных данных — Поддерживает перевод из методов-заглушек Distance, Within, IsValid и IsValidDetailed в эквивалентные встроенные функции SQL.

Определяемая пользователем функция расширения — Поддерживает перевод из метода-заглушки UserDefinedFunctionProvider.Invoke в соответствующую пользовательскую функцию.

Разное — Поддерживает перевод объединенных и условных операторов. Может переводить Contains в String CONTAINS, ARRAY_CONTAINS или SQL IN в зависимости от контекста.

Давайте посмотрим на пример, где мы будем использовать .Net SDK. Ниже приведены три документа, которые мы рассмотрим для этого примера.

Новый клиент 1

{ 
   "name": "New Customer 1", 
   "address": { 
      "addressType": "Main Office", 
      "addressLine1": "123 Main Street", 
		
      "location": { 
         "city": "Brooklyn", 
         "stateProvinceName": "New York" 
      },
	  
      "postalCode": "11229", 
      "countryRegionName": "United States" 
   }, 
}

Новый клиент 2

{ 
   "name": "New Customer 2", 
	
   "address": {
      "addressType": "Main Office", 
      "addressLine1": "678 Main Street", 
		
      "location": { 
         "city": "London", 
         "stateProvinceName": " London " 
      }, 
	  
      "postalCode": "11229", 
      "countryRegionName": "United Kingdom" 
   }, 
}

Новый клиент 3

{ 
   "name": "New Customer 3", 
	
   "address": { 
      "addressType": "Main Office", 
      "addressLine1": "12 Main Street", 
		
      "location": { 
         "city": "Brooklyn", 
         "stateProvinceName": "New York" 
      },
	  
      "postalCode": "11229", 
      "countryRegionName": "United States" 
   },
}

Ниже приведен код, в котором мы запрашиваем с помощью LINQ. Мы определили запрос LINQ в q , но он не будет выполняться, пока мы не запустим .ToList для него.

private static void QueryDocumentsWithLinq(DocumentClient client) { 
   Console.WriteLine(); 
   Console.WriteLine("**** Query Documents (LINQ) ****"); 
   Console.WriteLine();  
   Console.WriteLine("Quering for US customers (LINQ)"); 
   var q = 
      from d in client.CreateDocumentQuery<Customer>(collection.DocumentsLink) 
      where d.Address.CountryRegionName == "United States" 
		
   select new { 
      Id = d.Id, 
      Name = d.Name, 
      City = d.Address.Location.City 
   };
   
   var documents = q.ToList();  
   Console.WriteLine("Found {0} US customers", documents.Count); 
	
   foreach (var document in documents) { 
      var d = document as dynamic; 
      Console.WriteLine(" Id: {0}; Name: {1}; City: {2}", d.Id, d.Name, d.City); 
   }
   
   Console.WriteLine(); 
}

SDK преобразует наш запрос LINQ в синтаксис SQL для DocumentDB, генерируя предложение SELECT и WHERE на основе нашего синтаксиса LINQ.

Давайте вызовем вышеупомянутые запросы из задачи CreateDocumentClient.

private static async Task CreateDocumentClient() { 
   // Create a new instance of the DocumentClient 
   using (var client = new DocumentClient(new Uri(EndpointUrl), AuthorizationKey)) { 
      database = client.CreateDatabaseQuery("SELECT * FROM c WHERE c.id = 
         'myfirstdb'").AsEnumerable().First(); 
      collection = client.CreateDocumentCollectionQuery(database.CollectionsLink, 
         "SELECT * FROM c WHERE c.id = 'MyCollection'").AsEnumerable().First();  
      QueryDocumentsWithLinq(client); 
   } 
}

Когда приведенный выше код выполняется, он производит следующий вывод.