{"id":3569,"date":"2020-01-05T01:37:22","date_gmt":"2020-01-05T08:37:22","guid":{"rendered":"https:\/\/devblogs.microsoft.com\/odata\/?p=3569"},"modified":"2020-03-02T07:14:34","modified_gmt":"2020-03-02T14:14:34","slug":"integrating-cosmos-db-with-odata-part-3","status":"publish","type":"post","link":"https:\/\/devblogs.microsoft.com\/odata\/integrating-cosmos-db-with-odata-part-3\/","title":{"rendered":"Integrating Cosmos DB with OData (Part 3)"},"content":{"rendered":"<p>Sometimes requiring to build an entire ASP.NET Core application just for the purpose of exposing a RESTFul API endpoint to give your API consumers the ability to query, filter and order the data could be a bit of an overhead, especially if you are not planning on adding in any additional business logic between your data and it&#8217;s consumers.<\/p>\n<p>It&#8217;s not also a very cost effective solution when it comes to the development effort, maintenance, infrastructure and all the bells and whistles that accompany developing a custom ASP.NET Core API.<\/p>\n<p>If that&#8217;s the case for your task, Cosmos DB offers native support for OData out of the box without having to add an additional layer of infrastructure.<\/p>\n<p>In this article, we will discuss how you can leverage Cosmos DB native support for OData while exposing an API and leveraging a secure reliable geo-redundant communications between your clients and your data resources.<\/p>\n<p>&nbsp;<\/p>\n<h3>Setting Things Up<\/h3>\n<p>Let&#8217;s start with Azure Dashboard where we need to setup up our infrastructure.<\/p>\n<p style=\"padding-left: 40px;\">1. At the front page of Azure Dashboard, Click on the plus sign to <strong>Create a resource\u00a0<\/strong>as highlighted in the screenshot below:<\/p>\n<p><img decoding=\"async\" class=\"aligncenter size-full wp-image-3573\" src=\"https:\/\/devblogs.microsoft.com\/odata\/wp-content\/uploads\/sites\/23\/2020\/01\/Select-a-new-resource-1.png\" alt=\"\" width=\"1220\" height=\"194\" srcset=\"https:\/\/devblogs.microsoft.com\/odata\/wp-content\/uploads\/sites\/23\/2020\/01\/Select-a-new-resource-1.png 1220w, https:\/\/devblogs.microsoft.com\/odata\/wp-content\/uploads\/sites\/23\/2020\/01\/Select-a-new-resource-1-300x48.png 300w, https:\/\/devblogs.microsoft.com\/odata\/wp-content\/uploads\/sites\/23\/2020\/01\/Select-a-new-resource-1-1024x163.png 1024w, https:\/\/devblogs.microsoft.com\/odata\/wp-content\/uploads\/sites\/23\/2020\/01\/Select-a-new-resource-1-768x122.png 768w\" sizes=\"(max-width: 1220px) 100vw, 1220px\" \/><\/p>\n<p style=\"padding-left: 40px;\">2. Select <strong>Azure Cosmos DB<\/strong> Option from the list of cloud services presented in the next dialog:<\/p>\n<p><img decoding=\"async\" class=\"aligncenter wp-image-3575 \" src=\"https:\/\/devblogs.microsoft.com\/odata\/wp-content\/uploads\/sites\/23\/2020\/01\/Select-Azure-Cosmos-DB.png\" alt=\"\" width=\"500\" height=\"660\" srcset=\"https:\/\/devblogs.microsoft.com\/odata\/wp-content\/uploads\/sites\/23\/2020\/01\/Select-Azure-Cosmos-DB.png 652w, https:\/\/devblogs.microsoft.com\/odata\/wp-content\/uploads\/sites\/23\/2020\/01\/Select-Azure-Cosmos-DB-227x300.png 227w\" sizes=\"(max-width: 500px) 100vw, 500px\" \/><\/p>\n<p style=\"padding-left: 40px;\">3. In this page we are going to setup all the information needed to create a Cosmos DB instance as shows in the following screenshot:<\/p>\n<p><img decoding=\"async\" class=\"aligncenter wp-image-3578\" src=\"https:\/\/devblogs.microsoft.com\/odata\/wp-content\/uploads\/sites\/23\/2020\/01\/Filling-Instance-Information.png\" alt=\"\" width=\"1009\" height=\"844\" srcset=\"https:\/\/devblogs.microsoft.com\/odata\/wp-content\/uploads\/sites\/23\/2020\/01\/Filling-Instance-Information.png 1128w, https:\/\/devblogs.microsoft.com\/odata\/wp-content\/uploads\/sites\/23\/2020\/01\/Filling-Instance-Information-300x251.png 300w, https:\/\/devblogs.microsoft.com\/odata\/wp-content\/uploads\/sites\/23\/2020\/01\/Filling-Instance-Information-1024x857.png 1024w, https:\/\/devblogs.microsoft.com\/odata\/wp-content\/uploads\/sites\/23\/2020\/01\/Filling-Instance-Information-768x643.png 768w\" sizes=\"(max-width: 1009px) 100vw, 1009px\" \/><\/p>\n<p>After selecting the subscription you would like to use for your Cosmos DB, you will need to select the resource group where you need your Cosmos DB instance to reside. If you don&#8217;t have an existing resource group, you can click\u00a0<strong>Create new\u00a0<\/strong>link right below the resource group drop down to create a new resource group for your resources.<\/p>\n<p>You will also notice in the screenshot that we&#8217;ve chosen\u00a0<em>studentsdata\u00a0<\/em>as an account name for the purpose of this demo, but the most important part of this setup is to select the right <strong>API<\/strong> to ensure you can leverage the native support of OData, in our demo here, you will need to select\u00a0<strong>Azure Table <\/strong>which is the API Cosmos DB offers with OData support as we will discuss further in this article.<\/p>\n<p>You can also enable the Geo-Redundancy option for your instance to enable global distribution on your account across multiple regions, you can also enable that option later as your data needs grow, additionally you can also enable the Multi-region Writes which should allow you to take advantage of the provisioned throughput for your databases and containers across the globe, for the purpose of this demo, we will keep both options disabled.<\/p>\n<p style=\"padding-left: 40px;\">4.Once you have accomplished the aforementioned steps, click the <strong>Review + Create\u00a0<\/strong>button to review all the information you&#8217;ve entered as follows:<\/p>\n<p><img decoding=\"async\" class=\"aligncenter wp-image-3581\" src=\"https:\/\/devblogs.microsoft.com\/odata\/wp-content\/uploads\/sites\/23\/2020\/01\/ReviewAndCreateAzureCosmosTable-1.png\" alt=\"\" width=\"660\" height=\"597\" srcset=\"https:\/\/devblogs.microsoft.com\/odata\/wp-content\/uploads\/sites\/23\/2020\/01\/ReviewAndCreateAzureCosmosTable-1.png 743w, https:\/\/devblogs.microsoft.com\/odata\/wp-content\/uploads\/sites\/23\/2020\/01\/ReviewAndCreateAzureCosmosTable-1-300x271.png 300w\" sizes=\"(max-width: 660px) 100vw, 660px\" \/><\/p>\n<p>The process of creating a Cosmos DB instance takes between 5 &#8211; 10 minutes to be fully provisioned and deployed. Once the deployment is done click on\u00a0<strong>Go to resource <\/strong>blue button to start working with your Cosmos DB instance as shows in the following screenshot:<\/p>\n<p><img decoding=\"async\" class=\"aligncenter size-full wp-image-3584\" src=\"https:\/\/devblogs.microsoft.com\/odata\/wp-content\/uploads\/sites\/23\/2020\/01\/DeploymentCompleted.png\" alt=\"\" width=\"913\" height=\"245\" srcset=\"https:\/\/devblogs.microsoft.com\/odata\/wp-content\/uploads\/sites\/23\/2020\/01\/DeploymentCompleted.png 913w, https:\/\/devblogs.microsoft.com\/odata\/wp-content\/uploads\/sites\/23\/2020\/01\/DeploymentCompleted-300x81.png 300w, https:\/\/devblogs.microsoft.com\/odata\/wp-content\/uploads\/sites\/23\/2020\/01\/DeploymentCompleted-768x206.png 768w\" sizes=\"(max-width: 913px) 100vw, 913px\" \/>\nLet&#8217;s move on to the next part of this article, which is to create a table with some data so we can examine our OData querying options.<\/p>\n<p>&nbsp;<\/p>\n<h3>Adding Some Data<\/h3>\n<p>To add some data to your new instance, we will need to create a table or container for this data first, in order for you to do that follow the following steps.<\/p>\n<p style=\"padding-left: 40px;\">1. Click on the\u00a0<strong>Data Explorer\u00a0<\/strong>option to navigate to data manipulation and querying page as shows in the following screenshot:<\/p>\n<p><img decoding=\"async\" class=\"aligncenter size-full wp-image-3586\" src=\"https:\/\/devblogs.microsoft.com\/odata\/wp-content\/uploads\/sites\/23\/2020\/01\/Data-Explorer.png\" alt=\"\" width=\"247\" height=\"427\" srcset=\"https:\/\/devblogs.microsoft.com\/odata\/wp-content\/uploads\/sites\/23\/2020\/01\/Data-Explorer.png 247w, https:\/\/devblogs.microsoft.com\/odata\/wp-content\/uploads\/sites\/23\/2020\/01\/Data-Explorer-174x300.png 174w\" sizes=\"(max-width: 247px) 100vw, 247px\" \/><\/p>\n<p>&nbsp;<\/p>\n<p style=\"padding-left: 40px;\">2. Now in the new page, click\u00a0<strong>New Table\u00a0<\/strong>option at the top left corner to create a table that contains our sample data, once clicked, a dialog will appear from the right side to enable you to give your new data table a name, for the purpose of our demo here, we are going to call our new table\u00a0<em>students\u00a0<\/em>as highlighted in the screenshot below:<\/p>\n<p><img decoding=\"async\" class=\"aligncenter size-full wp-image-3589\" src=\"https:\/\/devblogs.microsoft.com\/odata\/wp-content\/uploads\/sites\/23\/2020\/01\/NewTable-1.png\" alt=\"\" width=\"803\" height=\"605\" srcset=\"https:\/\/devblogs.microsoft.com\/odata\/wp-content\/uploads\/sites\/23\/2020\/01\/NewTable-1.png 803w, https:\/\/devblogs.microsoft.com\/odata\/wp-content\/uploads\/sites\/23\/2020\/01\/NewTable-1-300x226.png 300w, https:\/\/devblogs.microsoft.com\/odata\/wp-content\/uploads\/sites\/23\/2020\/01\/NewTable-1-768x579.png 768w\" sizes=\"(max-width: 803px) 100vw, 803px\" \/><\/p>\n<p>&nbsp;<\/p>\n<p style=\"padding-left: 40px;\">3. Now that your table is created, you will need to navigate to your table by expanding\u00a0<em>TablesDB\u00a0<\/em>root item on the left hand in the navigation pane, then at the top click on\u00a0<strong>Add Entity\u00a0<\/strong>then start defining the properties of the student entity that you would like to store in the table as shows in the following screenshot:<\/p>\n<p><img decoding=\"async\" class=\"aligncenter size-full wp-image-3591\" src=\"https:\/\/devblogs.microsoft.com\/odata\/wp-content\/uploads\/sites\/23\/2020\/01\/AddNewEntity.png\" alt=\"\" width=\"1537\" height=\"391\" srcset=\"https:\/\/devblogs.microsoft.com\/odata\/wp-content\/uploads\/sites\/23\/2020\/01\/AddNewEntity.png 1537w, https:\/\/devblogs.microsoft.com\/odata\/wp-content\/uploads\/sites\/23\/2020\/01\/AddNewEntity-300x76.png 300w, https:\/\/devblogs.microsoft.com\/odata\/wp-content\/uploads\/sites\/23\/2020\/01\/AddNewEntity-1024x260.png 1024w, https:\/\/devblogs.microsoft.com\/odata\/wp-content\/uploads\/sites\/23\/2020\/01\/AddNewEntity-768x195.png 768w\" sizes=\"(max-width: 1537px) 100vw, 1537px\" \/><\/p>\n<p>You will notice that the\u00a0<em>PartitionKey\u00a0<\/em>and the\u00a0<em>RowKey\u00a0<\/em>are mandatory keys that you cannot remove or modify their types, they play the role of primary key in an equivalent relational database system, but you can, however add unique values and query the data based on these values.<\/p>\n<p>Since both properties are of string data types, you can choose to add whichever values you want in there, stringified Guids, numbers or any other form of unique identifiers.<\/p>\n<p>But as it shows in the screenshot above, we needed to add more properties to our entity here, we added\u00a0<em>Name\u00a0<\/em>with a data type string, and a\u00a0<em>Score\u00a0<\/em>with data type Int32. now let&#8217;s add some entities for our demo as shows in the following screenshot:<\/p>\n<p><img decoding=\"async\" class=\"aligncenter size-full wp-image-3593\" src=\"https:\/\/devblogs.microsoft.com\/odata\/wp-content\/uploads\/sites\/23\/2020\/01\/Data.png\" alt=\"\" width=\"859\" height=\"519\" srcset=\"https:\/\/devblogs.microsoft.com\/odata\/wp-content\/uploads\/sites\/23\/2020\/01\/Data.png 859w, https:\/\/devblogs.microsoft.com\/odata\/wp-content\/uploads\/sites\/23\/2020\/01\/Data-300x181.png 300w, https:\/\/devblogs.microsoft.com\/odata\/wp-content\/uploads\/sites\/23\/2020\/01\/Data-768x464.png 768w\" sizes=\"(max-width: 859px) 100vw, 859px\" \/><\/p>\n<p>&nbsp;<\/p>\n<h3>Consuming the Data<\/h3>\n<p>This is the part where we consume the data that we have created and examine our OData querying against our the\u00a0<em>students\u00a0<\/em>data table that we have created.<\/p>\n<p>But before we start writing any code, make sure you copy the\u00a0<strong>Connection String\u00a0<\/strong>of your Cosmos DB instance so you can establish a secure communication between your client and your Cosmos API.<\/p>\n<p>You can find the\u00a0<strong>Connection String\u00a0<\/strong>of your instance simply by going to the\u00a0<strong>Connection String\u00a0<\/strong>navigation option on the left hand side of your Azure instance and copying the\u00a0<strong>Primary Connection String <\/strong>as shows in the following screenshot:<\/p>\n<p><img decoding=\"async\" class=\"aligncenter size-full wp-image-3607\" src=\"https:\/\/devblogs.microsoft.com\/odata\/wp-content\/uploads\/sites\/23\/2020\/01\/ConnectionString-1.png\" alt=\"\" width=\"791\" height=\"561\" srcset=\"https:\/\/devblogs.microsoft.com\/odata\/wp-content\/uploads\/sites\/23\/2020\/01\/ConnectionString-1.png 791w, https:\/\/devblogs.microsoft.com\/odata\/wp-content\/uploads\/sites\/23\/2020\/01\/ConnectionString-1-300x213.png 300w, https:\/\/devblogs.microsoft.com\/odata\/wp-content\/uploads\/sites\/23\/2020\/01\/ConnectionString-1-768x545.png 768w\" sizes=\"(max-width: 791px) 100vw, 791px\" \/><\/p>\n<p>&nbsp;<\/p>\n<p style=\"padding-left: 40px;\">1. Now, let&#8217;s start by create a simple client as a <strong>Console Application\u00a0<\/strong>in Visual Studio to consume and query our data as follows:<\/p>\n<p><img decoding=\"async\" class=\"aligncenter wp-image-3599\" src=\"https:\/\/devblogs.microsoft.com\/odata\/wp-content\/uploads\/sites\/23\/2020\/01\/NewConsoleApp.png\" alt=\"\" width=\"742\" height=\"507\" srcset=\"https:\/\/devblogs.microsoft.com\/odata\/wp-content\/uploads\/sites\/23\/2020\/01\/NewConsoleApp.png 850w, https:\/\/devblogs.microsoft.com\/odata\/wp-content\/uploads\/sites\/23\/2020\/01\/NewConsoleApp-300x205.png 300w, https:\/\/devblogs.microsoft.com\/odata\/wp-content\/uploads\/sites\/23\/2020\/01\/NewConsoleApp-768x525.png 768w\" sizes=\"(max-width: 742px) 100vw, 742px\" \/><\/p>\n<p>We will be going with a\u00a0<strong>Console App (.NET Core)\u00a0<\/strong>in this demo, let&#8217;s call our App\u00a0<em>StudentsDataClient.<\/em><\/p>\n<p style=\"padding-left: 40px;\">2. We will need to add a nuget package to enable the authentication and communication, querying and navigation between our simple app and our Cosmos DB students table, the nuget package is\u00a0<a href=\"https:\/\/www.nuget.org\/packages\/Microsoft.Azure.Cosmos.Table\"><strong>Microsoft.Azure.Cosmos.Table<\/strong><\/a> specifically version 1.0.6. You can add the package simply by using\u00a0<strong>Manage Nuget Packages\u00a0<\/strong>option in Visual Studio or by simply typing the following command in the\u00a0<strong>Package Manager Console:<\/strong><\/p>\n<pre class=\"lang:ps decode:true \">Install-Package Microsoft.Azure.Cosmos.Table -Version 1.0.6<\/pre>\n<p style=\"padding-left: 40px;\">3. Now, that we had our project setup, let&#8217;s start by creating a model that reflects the same properties we have created in our <em>students\u00a0<\/em>Cosmos DB table, so, in a new file let&#8217;s call it\u00a0<em>Student.cs\u00a0<\/em>let&#8217;s create the following model:<\/p>\n<pre class=\"lang:default decode:true\">using Microsoft.Azure.Cosmos.Table;\r\n\r\nnamespace StudentsDataClient\r\n{\r\n    public class Student : TableEntity\r\n    {\r\n        public string? Name { get; set; }\r\n        public int? Score { get; set; }\r\n    }\r\n}\r\n<\/pre>\n<p>You will notice that our\u00a0<strong>Student\u00a0<\/strong>model here inherits from another model called\u00a0<strong>TableEntity,\u00a0<\/strong>this inheritance is necessary to include all the other properties that a Cosmos DB Table record has, such as the\u00a0<em>PartitionKey, RowKey, Timestamp\u00a0<\/em>in addition to a native implementation of\u00a0<em>ReadEntity\u00a0<\/em>and\u00a0<em>WriteEntity\u00a0<\/em>functions which are needed to map a Cosmos DB record to a strongly typed model for both reading from and writing to your table.<\/p>\n<p>You can also override these methods and properties or simply replace\u00a0<strong>TableEntity\u00a0<\/strong>with\u00a0<strong>ITableEntity\u00a0<\/strong>and start implementing all the aforementioned properties and functions.<\/p>\n<p>You will also notice that we defined all our properties here as nullable with a question mark by the type of each, this enables us to ignore properties that are discarded in an OData query, otherwise the return result will be the initial value of the primitive type of the property, for instance,\u00a0<em>Score\u00a0<\/em>would return 0&#8217;s.<\/p>\n<p style=\"padding-left: 40px;\">4. With our model being implemented, let&#8217;s instantiate a Cosmos DB client to establish a secure communication while retrieving everything in our table with an empty query as follows:<\/p>\n<pre class=\"lang:c# decode:true\">using System.Threading.Tasks;\r\nusing Microsoft.Azure.Cosmos.Table;\r\n\r\nnamespace StudentsDataClient\r\n{\r\n    class Program\r\n    {\r\n        static async Task Main(string[] args)\r\n        {\r\n            string connectionString = \"YOUR_PRIMARY_CONNECTION_STRING\";\r\n            CloudStorageAccount storageAccount = CloudStorageAccount.Parse(connectionString);\r\n            CloudTableClient tableClient = storageAccount.CreateCloudTableClient();\r\n\r\n            CloudTable table = tableClient.GetTableReference(\"students\");\r\n            TableQuery&lt;Student&gt; tableQuery = new TableQuery&lt;Student&gt;();\r\n            \r\n            TableQuerySegment&lt;Student&gt; studentsSegment = \r\n                await table.ExecuteQuerySegmentedAsync(tableQuery, token: null);\r\n            \r\n            studentsSegment.Results.ForEach(i =&gt; \r\n                Console.WriteLine(\"{0,5} {1,10} {2,-10}\", i.PartitionKey, i.Name, i.Score));\r\n            \r\n            Console.ReadKey();\r\n        }\r\n    }\r\n}\r\n<\/pre>\n<p>Let&#8217;s walk through the previous code snippet:<\/p>\n<p>First of all make sure you reference\u00a0<strong>Microsoft.Azure.Cosmos.Table\u00a0<\/strong>in your usings so you can access all the models, methods and functionality the library offers.<\/p>\n<p>Secondly, make sure you change your main method from by synchronous to asynchronous by changing the return type from void to Task and adding the async option. you will need to do that so you can await and execute asynchronous calls in your Main method.<\/p>\n<p>Asynchronous Main methods were introduced with C# 7.1 &#8211; you will want to make sure you&#8217;re using that version or later to establish this.<\/p>\n<p>We have also used the\u00a0<strong>Connection String\u00a0<\/strong>variable to contain the reference we have copied from our Cosmos DB instance, please refer to the beginning of this part to find out where to get that value in Azure.<\/p>\n<p>The rest of the code is simply a validation\/parsing of the connection string then using a\u00a0<strong>CreateCloudTableClient\u00a0<\/strong>factory method to instantiate Cosmos DB table client for our further communications.<\/p>\n<p>We also, reference the\u00a0<em>students\u00a0<\/em>table to target that particular data container in our Cosmos DB account, this step is important because a Cosmos DB account could contain many, many other tables.<\/p>\n<p>Our\u00a0<strong>TableQuery\u00a0<\/strong>in this basic example is completely empty, but in the next steps I&#8217;m going to show you how you can leverage that object to run OData queries shortly &#8211; but for now, running the code above results the following Console output as follows:<\/p>\n<pre class=\"lang:default decode:true\">    1     Hassan 155\r\n    2       Josh 133\r\n    3       Todd 189\r\n    4     Jackie 175\r\n    5    Sandeep 199\r\n    6      Kailu 211\r\n    7     Vishwa 183\r\n    8      Viral 125<\/pre>\n<h3><\/h3>\n<p>&nbsp;<\/p>\n<h3>OData Querying<\/h3>\n<p>Now that we have successfully retrieved all the data we entered in our Cosmos DB table, let&#8217;s execute some of the powerful features of OData.<\/p>\n<p>&nbsp;<\/p>\n<h4>Filtering<\/h4>\n<p>Let&#8217;s start with the filtering feature of OData to only return students with score higher than 150 as follows:<\/p>\n<pre class=\"lang:c# decode:true\">TableQuery&lt;Student&gt; tableQuery = new TableQuery&lt;Student&gt;\r\n{\r\n     FilterString = \"Score gt 150\"\r\n};<\/pre>\n<p>The result will be as follows:<\/p>\n<pre class=\"lang:default decode:true \">    1     Hassan 155\r\n    3       Todd 189\r\n    4     Jackie 175\r\n    5    Sandeep 199\r\n    6      Kailu 211\r\n    7     Vishwa 183\r\n<\/pre>\n<p>You can also establish the same filtering process by modifying your code as follows:<\/p>\n<pre class=\"lang:c# decode:true \">TableQuery&lt;Student&gt; tableQuery = new TableQuery&lt;Student&gt;();\r\ntableQuery.Where(\"Score gt 150\");<\/pre>\n<p>And here&#8217;s a third option as well:<\/p>\n<pre class=\"lang:default decode:true \">TableQuery&lt;Student&gt; tableQuery = new TableQuery&lt;Student&gt;();\r\nstring filter = TableQuery.GenerateFilterConditionForInt(\"Score\", QueryComparisons.GreaterThan, 150);\r\ntableQuery.Where(filter);<\/pre>\n<p>For filtering with the last option, the library offers multiple methods for comparing several primitive data types, such as <em>GenerateFilterConditionForBinary, GenerateFilterConditionForDate, GenerateFilterConditionForInt\u00a0<\/em>and many other options, the default method GenerateFilterCondition compares against strings by default.<\/p>\n<p>You can also use the same pattern to combine multiple filters as follows:<\/p>\n<pre class=\"lang:c# decode:true \">TableQuery&lt;Student&gt; tableQuery = new TableQuery&lt;Student&gt;();\r\n            \r\nstring filter = TableQuery.CombineFilters(\r\n     TableQuery.GenerateFilterConditionForInt(\"Score\", QueryComparisons.GreaterThan, 150),\r\n     TableOperators.And,\r\n     TableQuery.GenerateFilterCondition(\"Name\", QueryComparisons.Equal, \"Hassan\"));\r\n            \r\ntableQuery.Where(filter);<\/pre>\n<p>&nbsp;<\/p>\n<h4>Selecting<\/h4>\n<p>Now, let&#8217;s experiment with selecting particular properties off of our results, for instance, if we only care about students names, regardless of their score, we can implement the following code:<\/p>\n<pre class=\"lang:c# decode:true \">TableQuery&lt;Student&gt; tableQuery = new TableQuery&lt;Student&gt;();\r\nList&lt;string&gt; columns = new List&lt;string&gt; { \"Name\" };\r\ntableQuery.Select(columns);<\/pre>\n<p>The above code will yield the following results:<\/p>\n<pre class=\"lang:default decode:true \">    1     Hassan\r\n    2       Josh\r\n    3       Todd\r\n    4     Jackie\r\n    5    Sandeep\r\n    6      Kailu\r\n    7     Vishwa\r\n    8      Viral\r\n<\/pre>\n<p>The <em>Score\u00a0<\/em>property are not in display in our code because we declared it as nullable property, therefore the Console writer will ignore it if not fulfilled by Cosmos API response.<\/p>\n<p>&nbsp;<\/p>\n<h4>Ordering<\/h4>\n<p>You can also execute ordering in an ascending or descending fashion based on a particular property such as\u00a0<em>Name<\/em> as follows:<\/p>\n<pre class=\"lang:default decode:true \">TableQuery&lt;Student&gt; tableQuery = new TableQuery&lt;Student&gt;();\r\ntableQuery.OrderBy(\"Name\");<\/pre>\n<p>The above code result the following details:<\/p>\n<pre class=\"lang:default decode:true \">    1     Hassan 155\r\n    4     Jackie 175\r\n    2       Josh 133\r\n    6      Kailu 211\r\n    5    Sandeep 199\r\n    3       Todd 189\r\n    8      Viral 125\r\n    7     Vishwa 183\r\n<\/pre>\n<p>You can also leverage the ordering in descending fashion by using\u00a0<em>OrderByDesc\u00a0<\/em>the exact same way.<\/p>\n<p>&nbsp;<\/p>\n<h4>Take<\/h4>\n<p>You can also leverage the\u00a0<strong>Take\u00a0<\/strong>functionality by getting only a specific count of the final result to be returned as follows:<\/p>\n<pre class=\"lang:c# decode:true \">TableQuery&lt;Student&gt; tableQuery = new TableQuery&lt;Student&gt;();\r\ntableQuery.Take(take: 3);<\/pre>\n<p>The above code should returning the following results:<\/p>\n<pre class=\"lang:default decode:true \">    1     Hassan 155\r\n    2       Josh 133\r\n    3       Todd 189\r\n<\/pre>\n<p>&nbsp;<\/p>\n<h3>Final Notes<\/h3>\n<ol>\n<li>The Cosmos DB team has an extensive documentation about all the capabilities of the technology and thorough details on the client library you can find that documentation in this <a href=\"https:\/\/docs.microsoft.com\/en-us\/azure\/cosmos-db\/tutorial-query-table\">link.<\/a><\/li>\n<li>There are few capabilities the library &amp; the API do not offer such as\u00a0<strong>IN<\/strong> and <strong>Expand <\/strong>functionality, mainly due to the non-relational nature of Cosmos and Table API.<\/li>\n<li>This is the <a href=\"https:\/\/github.com\/hassanhabib\/ODataCosmosDBClient\">link<\/a> to a github repository for the code we used in this article.<\/li>\n<\/ol>\n","protected":false},"excerpt":{"rendered":"<p>Sometimes requiring to build an entire ASP.NET Core application just for the purpose of exposing a RESTFul API endpoint to give your API consumers the ability to query, filter and order the data could be a bit of an overhead, especially if you are not planning on adding in any additional business logic between your [&hellip;]<\/p>\n","protected":false},"author":3348,"featured_media":3345,"comment_status":"open","ping_status":"closed","sticky":false,"template":"","format":"standard","meta":{"_acf_changed":false,"footnotes":""},"categories":[1],"tags":[],"class_list":["post-3569","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-odata"],"acf":[],"blog_post_summary":"<p>Sometimes requiring to build an entire ASP.NET Core application just for the purpose of exposing a RESTFul API endpoint to give your API consumers the ability to query, filter and order the data could be a bit of an overhead, especially if you are not planning on adding in any additional business logic between your [&hellip;]<\/p>\n","_links":{"self":[{"href":"https:\/\/devblogs.microsoft.com\/odata\/wp-json\/wp\/v2\/posts\/3569","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/devblogs.microsoft.com\/odata\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/devblogs.microsoft.com\/odata\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/odata\/wp-json\/wp\/v2\/users\/3348"}],"replies":[{"embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/odata\/wp-json\/wp\/v2\/comments?post=3569"}],"version-history":[{"count":0,"href":"https:\/\/devblogs.microsoft.com\/odata\/wp-json\/wp\/v2\/posts\/3569\/revisions"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/odata\/wp-json\/wp\/v2\/media\/3345"}],"wp:attachment":[{"href":"https:\/\/devblogs.microsoft.com\/odata\/wp-json\/wp\/v2\/media?parent=3569"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/odata\/wp-json\/wp\/v2\/categories?post=3569"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/odata\/wp-json\/wp\/v2\/tags?post=3569"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}