{"id":13087,"date":"2022-04-18T11:02:34","date_gmt":"2022-04-18T18:02:34","guid":{"rendered":"https:\/\/www.couchbase.com\/blog\/?p=13087"},"modified":"2025-06-13T20:56:46","modified_gmt":"2025-06-14T03:56:46","slug":"asp-net-crud-nosql-part-2","status":"publish","type":"post","link":"https:\/\/www.couchbase.com\/blog\/asp-net-crud-nosql-part-2\/","title":{"rendered":"ASP.NET Core CRUD with NoSQL: Part 2"},"content":{"rendered":"<p><span style=\"font-weight: 400;\">CRUD stands for Create, Read, Update, and Delete. In part 2, we\u2019ll look at R for Read, and build an ASP.NET Core endpoint to read data from Couchbase using SQL.<\/span><\/p>\n<p><span style=\"font-weight: 400;\">Make sure to read <\/span><a href=\"https:\/\/www.couchbase.com\/blog\/asp-net-core-crud-with-nosql-part-1\" target=\"_blank\" rel=\"noopener\"><span style=\"font-weight: 400;\">part 1 of this series<\/span><\/a><span style=\"font-weight: 400;\">, which covers setup and configuration of your ASP.NET Core &#8220;wishlist&#8221; project.<\/span><\/p>\n<h2><b>SQL++ to read<\/b><\/h2>\n<p><span style=\"font-weight: 400;\">Couchbase is unique among NoSQL databases in that it supports a <\/span><a href=\"https:\/\/cloud.couchbase.com\/sign-up\" target=\"_blank\" rel=\"noopener\"><span style=\"font-weight: 400;\">full SQL implementation<\/span><\/a><span style=\"font-weight: 400;\"> (called SQL++, n\u00e9e N1QL) to query JSON data.<\/span><\/p>\n<p><span style=\"font-weight: 400;\">SQL++ is not a watered-down &#8220;SQL-like&#8221; language. With SQL++, you have <\/span><a href=\"https:\/\/docs.couchbase.com\/server\/current\/n1ql\/n1ql-language-reference\/join.html\" target=\"_blank\" rel=\"noopener\"><span style=\"font-weight: 400;\">JOINs<\/span><\/a><span style=\"font-weight: 400;\">, <\/span><a href=\"https:\/\/docs.couchbase.com\/server\/current\/n1ql\/n1ql-language-reference\/with.html\" target=\"_blank\" rel=\"noopener\"><span style=\"font-weight: 400;\">CTEs\/WITH<\/span><\/a><span style=\"font-weight: 400;\">, <\/span><a href=\"https:\/\/docs.couchbase.com\/server\/current\/n1ql\/n1ql-language-reference\/update.html\" target=\"_blank\" rel=\"noopener\"><span style=\"font-weight: 400;\">UPDATE<\/span><\/a><span style=\"font-weight: 400;\">, <\/span><a href=\"https:\/\/docs.couchbase.com\/server\/current\/n1ql\/n1ql-language-reference\/insert.html\" target=\"_blank\" rel=\"noopener\"><span style=\"font-weight: 400;\">INSERT<\/span><\/a><span style=\"font-weight: 400;\">, <\/span><a href=\"https:\/\/docs.couchbase.com\/server\/current\/n1ql\/n1ql-language-reference\/delete.html\" target=\"_blank\" rel=\"noopener\"><span style=\"font-weight: 400;\">DELETE<\/span><\/a><span style=\"font-weight: 400;\">, <\/span><a href=\"https:\/\/docs.couchbase.com\/server\/current\/n1ql\/n1ql-language-reference\/merge.html\" target=\"_blank\" rel=\"noopener\"><span style=\"font-weight: 400;\">MERGE<\/span><\/a><span style=\"font-weight: 400;\">, <\/span><a href=\"https:\/\/docs.couchbase.com\/server\/current\/n1ql\/n1ql-language-reference\/groupby.html\" target=\"_blank\" rel=\"noopener\"><span style=\"font-weight: 400;\">aggregation\/GROUP BY<\/span><\/a><span style=\"font-weight: 400;\">, <\/span><a href=\"https:\/\/docs.couchbase.com\/server\/current\/n1ql\/n1ql-language-reference\/begin-transaction.html\" target=\"_blank\" rel=\"noopener\"><span style=\"font-weight: 400;\">BEGIN\/COMMIT\/ROLLBACK<\/span><\/a><span style=\"font-weight: 400;\">, and more.<\/span><\/p>\n<p><span style=\"font-weight: 400;\">On top of that (the &#8220;++&#8221;), you also get features to deal with JSON data, like <\/span><a href=\"https:\/\/docs.couchbase.com\/server\/current\/n1ql\/n1ql-language-reference\/datatypes.html#datatype-missing\" target=\"_blank\" rel=\"noopener\"><span style=\"font-weight: 400;\">MISSING<\/span><\/a><span style=\"font-weight: 400;\">, <\/span><a href=\"https:\/\/docs.couchbase.com\/server\/current\/n1ql\/n1ql-language-reference\/nest.html\" target=\"_blank\" rel=\"noopener\"><span style=\"font-weight: 400;\">NEST<\/span><\/a><span style=\"font-weight: 400;\">, <\/span><a href=\"https:\/\/docs.couchbase.com\/server\/current\/n1ql\/n1ql-language-reference\/arrayfun.html\" target=\"_blank\" rel=\"noopener\"><span style=\"font-weight: 400;\">ARRAY_* functions<\/span><\/a><span style=\"font-weight: 400;\">, <\/span><a href=\"https:\/\/docs.couchbase.com\/server\/current\/n1ql\/n1ql-language-reference\/objectfun.html\" target=\"_blank\" rel=\"noopener\"><span style=\"font-weight: 400;\">OBJECT_* functions<\/span><\/a><span style=\"font-weight: 400;\">, and more.<\/span><\/p>\n<p><span style=\"font-weight: 400;\">For this simple CRUD application, we\u2019ll use a SQL++ <\/span><span style=\"font-weight: 400;\">SELECT<\/span><span style=\"font-weight: 400;\"> query (and index) to return <\/span><b>all<\/b><span style=\"font-weight: 400;\"> items from my wishlist.<\/span><\/p>\n<h2><b>Writing your first SQL++ query<\/b><\/h2>\n<p><span style=\"font-weight: 400;\">First, let\u2019s try writing a SQL++ query to get all wishlist items right in the <\/span><a href=\"https:\/\/docs.couchbase.com\/cloud\/clusters\/query-service\/query-workbench.html\" target=\"_blank\" rel=\"noopener\"><span style=\"font-weight: 400;\">Capella Query Workbench<\/span><\/a><span style=\"font-weight: 400;\">.<\/span><\/p>\n<p><span style=\"font-weight: 400;\">To start with, try:<\/span><\/p>\n<pre class=\"decode-attributes:false lang:tsql decode:true \">SELECT * FROM demo._default.wishlist;<\/pre>\n<p><span style=\"font-weight: 400;\">When you do this, you should get an error message. Something like:<\/span><\/p>\n<pre class=\"decode-attributes:false lang:default decode:true \">`no index available on keyspace default:demo._default.wishlist that matches your query. Use CREATE PRIMARY INDEX` ...<\/pre>\n<p><span style=\"font-weight: 400;\">This is expected behavior. (Most) SQL++ queries in Couchbase will not run unless there is at least one index available for them.<\/span><\/p>\n<p><span style=\"font-weight: 400;\">No problem. Create a simple <\/span><a href=\"https:\/\/docs.couchbase.com\/server\/current\/n1ql\/n1ql-language-reference\/createprimaryindex.html\" target=\"_blank\" rel=\"noopener\"><span style=\"font-weight: 400;\">PRIMARY INDEX<\/span><\/a><span style=\"font-weight: 400;\"> with a command like this:<\/span><\/p>\n<pre class=\"decode-attributes:false lang:tsql decode:true \">CREATE PRIMARY INDEX `ix_wishlist` ON `demo`.`_default`.`wishlist`<\/pre>\n<p><span style=\"font-weight: 400;\">Primary indexes are generally not meant to be used in a typical production environment, but they are very helpful for a development environment, since they guarantee that <\/span><b>any<\/b><span style=\"font-weight: 400;\"> SQL++ query will run on the indexed collection (though not as efficient as a properly indexed collection). Once you start creating more complex SQL++ queries, you can use the <\/span><a href=\"https:\/\/docs.couchbase.com\/cloud\/clusters\/query-service\/query-workbench.html#index-advisor\" target=\"_blank\" rel=\"noopener\"><span style=\"font-weight: 400;\">&#8220;Advise&#8221; button on the Query Workbench<\/span><\/a><span style=\"font-weight: 400;\"> to get suggestions of more efficient indexes to create (and you should avoid using <\/span><span style=\"font-weight: 400;\">SELECT *<\/span><span style=\"font-weight: 400;\"> whenever you can \ud83d\ude06).<\/span><\/p>\n<p><span style=\"font-weight: 400;\">After creating the index, retry the above <\/span><span style=\"font-weight: 400;\">SELECT<\/span><span style=\"font-weight: 400;\"> query again, and the results should look like this:<\/span><\/p>\n<pre class=\"decode-attributes:false lang:tsql decode:true \">[\r\n\u00a0 {\r\n\u00a0 \u00a0 \"wishlist\": {\r\n\u00a0 \u00a0 \u00a0 \"name\": \"Skyline Chili T-Shirt\"\r\n\u00a0 \u00a0 }\r\n\u00a0 },\r\n\u00a0 {\r\n\u00a0 \u00a0 \"wishlist\": {\r\n\u00a0 \u00a0 \u00a0 \"name\": \"Joey Votto jersey\"\r\n\u00a0 \u00a0 }\r\n\u00a0 }\r\n]<\/pre>\n<p><span style=\"font-weight: 400;\">Almost there. Try imagining this array of objects being serialized to a C# <\/span><em><span style=\"font-weight: 400;\">List&lt;WishlistItem&gt;<\/span><\/em><span style=\"font-weight: 400;\">. It wouldn\u2019t quite work, because the objects are nested with the collection name. So, I\u2019ve gotten into a habit of aliasing the collections, like this:<\/span><\/p>\n<pre class=\"decode-attributes:false lang:tsql decode:true \">SELECT w.* FROM demo._default.wishlist w;<\/pre>\n<p><span style=\"font-weight: 400;\">Which produces the result:<\/span><\/p>\n<pre class=\"decode-attributes:false lang:js decode:true \">[\r\n\u00a0 {\r\n\u00a0 \u00a0 \"name\": \"Skyline Chili T-Shirt\"\r\n\u00a0 },\r\n\u00a0 {\r\n\u00a0 \u00a0 \"name\": \"Joey Votto jersey\"\r\n\u00a0 }\r\n]<\/pre>\n<p><span style=\"font-weight: 400;\">Looking good, but there\u2019s still something missing. Where are those GUIDs that we used for the document keys? Couchbase doesn\u2019t store them as data; it stores them as <\/span><b>metadata<\/b><span style=\"font-weight: 400;\">. SQL++ provides the <\/span><em><span style=\"font-weight: 400;\">META()<\/span><\/em><span style=\"font-weight: 400;\"> function to query metadata. Use <\/span><em><span style=\"font-weight: 400;\">META().id<\/span><\/em><span style=\"font-weight: 400;\"> like this:<\/span><\/p>\n<pre class=\"decode-attributes:false lang:tsql decode:true \">SELECT META(w).id, w.* FROM demo._default.wishlist w;<\/pre>\n<p><span style=\"font-weight: 400;\">And that finally gives us a result of:<\/span><\/p>\n<pre class=\"decode-attributes:false lang:js decode:true \">[\r\n\u00a0 {\r\n\u00a0 \u00a0 \"id\": \"2dab198b-1836-4409-9bdf-17275a2b2462\",\r\n\u00a0 \u00a0 \"name\": \"Skyline Chili T-Shirt\"\r\n\u00a0 },\r\n\u00a0 {\r\n\u00a0 \u00a0 \"id\": \"31c9cc33-8dfe-440c-bd1b-bb038939d2e0\",\r\n\u00a0 \u00a0 \"name\": \"Joey Votto jersey\"\r\n\u00a0 }\r\n]<\/pre>\n<p><span style=\"font-weight: 400;\">This will serialize nicely into <\/span><em><span style=\"font-weight: 400;\">WishlistItem<\/span><\/em><span style=\"font-weight: 400;\"> objects, using the class created in part 1.<\/span><\/p>\n<h2><b>Using SQL++ in ASP.NET Core<\/b><\/h2>\n<p><span style=\"font-weight: 400;\">Let\u2019s get that SQL++ query we just wrote into an ASP.NET Core endpoint.<\/span><\/p>\n<p><span style=\"font-weight: 400;\">In <em>GiftsController<\/em>, create a endpoint called <em>GetAll<\/em>:<\/span><\/p>\n<pre class=\"decode-attributes:false lang:c# decode:true\">[HttpGet]\r\n[Route(\"api\/getall\")]\r\npublic async Task&lt;IActionResult&gt; GetAll()\r\n{\r\n\r\n}<\/pre>\n<p><span style=\"font-weight: 400;\">To execute SQL++, we need to get an object of type <\/span><span style=\"font-weight: 400;\">Cluster<\/span><span style=\"font-weight: 400;\">. SQL++ runs at the cluster level (not bucket, or scope, or collection, since it may need to <\/span><span style=\"font-weight: 400;\">JOIN<\/span><span style=\"font-weight: 400;\">\/<\/span><span style=\"font-weight: 400;\">UNION<\/span><span style=\"font-weight: 400;\"> between them). We could go back and add <\/span><a href=\"https:\/\/docs.couchbase.com\/dotnet-sdk\/current\/howtos\/managing-connections.html#injecting-the-couchbase-cluster\" target=\"_blank\" rel=\"noopener\"><span style=\"font-weight: 400;\">ClusterProvider<\/span><\/a><span style=\"font-weight: 400;\"> as a constructor parameter. If this endpoint was going to only work with SQL++, that would be a good idea. However, let\u2019s stick with what we created in part 1. We have an object of type <\/span><em><span style=\"font-weight: 400;\">BucketProvider<\/span><\/em><span style=\"font-weight: 400;\">. From that object, you can get a object of type <\/span><span style=\"font-weight: 400;\">Cluster<\/span><span style=\"font-weight: 400;\">:<\/span><\/p>\n<pre class=\"decode-attributes:false lang:c# decode:true\">[HttpGet]\r\n[Route(\"api\/getall\")]\r\npublic async Task&lt;IActionResult&gt; GetAll()\r\n{\r\n  var bucket = await _bucketProvider.GetBucketAsync(\"demo\");\r\n  var cluster = bucket.Cluster;\r\n\r\n  \/\/ ... snip ...\r\n}<\/pre>\n<p><span style=\"font-weight: 400;\">A <\/span><span style=\"font-weight: 400;\">cluster<\/span><span style=\"font-weight: 400;\"> object is how ASP.NET Core will interact with a Couchbase cluster in a variety of ways. For now, we\u2019re interested in its <\/span><em><span style=\"font-weight: 400;\">QueryAsync&lt;T&gt;<\/span><\/em><span style=\"font-weight: 400;\"> method:<\/span><\/p>\n<pre class=\"decode-attributes:false lang:c# decode:true\">[HttpGet]\r\n[Route(\"api\/getall\")]\r\npublic async Task&lt;IActionResult&gt; GetAll()\r\n{\r\n  var bucket = await _bucketProvider.GetBucketAsync(\"demo\");\r\n  var cluster = bucket.Cluster;\r\n\r\n  var result = await cluster.QueryAsync&lt;WishlistItem&gt;(\r\n    \"SELECT META(w).id, w.* FROM demo._default.wishlist w;\"\r\n  );\r\n\r\n  return Ok(result);\r\n}<\/pre>\n<p><span style=\"font-weight: 400;\">Make sure you have the following <\/span><span style=\"font-weight: 400;\">using<\/span><span style=\"font-weight: 400;\"> statements at the top of your <em>GiftsController.cs<\/em> file:<\/span><\/p>\n<pre class=\"decode-attributes:false lang:c# decode:true\">using AspNetCoreTutorial.Models;\r\nusing Microsoft.AspNetCore.Mvc;\r\nusing Couchbase;\r\nusing Couchbase.Query;\r\nusing Couchbase.Extensions.DependencyInjection;<\/pre>\n<p><span style=\"font-weight: 400;\">One more thing to note. When executing SQL++, there are a number of <\/span><a href=\"https:\/\/docs.couchbase.com\/dotnet-sdk\/current\/howtos\/n1ql-queries-with-sdk.html#scan-consistency\" target=\"_blank\" rel=\"noopener\"><span style=\"font-weight: 400;\">(scan) consistency options<\/span><\/a><span style=\"font-weight: 400;\">. The default is <\/span><em><span style=\"font-weight: 400;\">ScanConsistency.NotBounded<\/span><\/em><span style=\"font-weight: 400;\">. This setting means that the query engine will <\/span><b>not<\/b><span style=\"font-weight: 400;\"> wait on indexes to finish updating before returning results. This is the most performant option. However, in some situations, you will want stronger index consistency. Couchbase provides <\/span><em><span style=\"font-weight: 400;\">RequestPlus<\/span><\/em><span style=\"font-weight: 400;\"> and <\/span><em><span style=\"font-weight: 400;\">AtPlus<\/span><\/em><span style=\"font-weight: 400;\">.<\/span><\/p>\n<h2><b>Try out the ASP.NET Core Endpoint<\/b><\/h2>\n<p><span style=\"font-weight: 400;\">From Visual Studio, <strong>Ctrl+F5<\/strong> will start the app. You should see an OpenAPI \/ Swagger page in your browser.<\/span><\/p>\n<p><img loading=\"lazy\" decoding=\"async\" class=\"alignnone size-full wp-image-13088\" src=\"https:\/\/www.couchbase.com\/blog\/wp-content\/uploads\/2022\/04\/image1-1.png\" alt=\"ASP.NET app reading from Couchbase\" width=\"827\" height=\"452\" srcset=\"https:\/\/www.couchbase.com\/blog\/wp-content\/uploads\/sites\/1\/2022\/04\/image1-1.png 827w, https:\/\/www.couchbase.com\/blog\/wp-content\/uploads\/sites\/1\/2022\/04\/image1-1-300x164.png 300w, https:\/\/www.couchbase.com\/blog\/wp-content\/uploads\/sites\/1\/2022\/04\/image1-1-768x420.png 768w, https:\/\/www.couchbase.com\/blog\/wp-content\/uploads\/sites\/1\/2022\/04\/image1-1-20x11.png 20w\" sizes=\"auto, (max-width: 827px) 100vw, 827px\" \/><\/p>\n<p><span style=\"font-weight: 400;\">(Ignore <em>WeatherForecast<\/em>, that just came with the Visual Studio template).<\/span><\/p>\n<p><span style=\"font-weight: 400;\">Click on the endpoint to try it out. There are no parameters to specify, so just click <strong>Execute<\/strong>.<\/span><\/p>\n<p><img loading=\"lazy\" decoding=\"async\" class=\"alignnone size-full wp-image-13089\" src=\"https:\/\/www.couchbase.com\/blog\/wp-content\/uploads\/2022\/04\/image2-1.png\" alt=\"Testing an ASP.NET endpoint and Couchbase\" width=\"806\" height=\"809\" srcset=\"https:\/\/www.couchbase.com\/blog\/wp-content\/uploads\/sites\/1\/2022\/04\/image2-1.png 806w, https:\/\/www.couchbase.com\/blog\/wp-content\/uploads\/sites\/1\/2022\/04\/image2-1-300x301.png 300w, https:\/\/www.couchbase.com\/blog\/wp-content\/uploads\/sites\/1\/2022\/04\/image2-1-150x150.png 150w, https:\/\/www.couchbase.com\/blog\/wp-content\/uploads\/sites\/1\/2022\/04\/image2-1-768x771.png 768w, https:\/\/www.couchbase.com\/blog\/wp-content\/uploads\/sites\/1\/2022\/04\/image2-1-65x65.png 65w, https:\/\/www.couchbase.com\/blog\/wp-content\/uploads\/sites\/1\/2022\/04\/image2-1-50x50.png 50w, https:\/\/www.couchbase.com\/blog\/wp-content\/uploads\/sites\/1\/2022\/04\/image2-1-20x20.png 20w\" sizes=\"auto, (max-width: 806px) 100vw, 806px\" \/><\/p>\n<p><span style=\"font-weight: 400;\">You now have the &#8220;R&#8221; of CRUD in place.<\/span><\/p>\n<h2><b>What\u2019s next?<\/b><\/h2>\n<p><span style=\"font-weight: 400;\">The ASP.NET Core project is connected to Couchbase Capella, and it is reading data via SQL++.<\/span><\/p>\n<p><span style=\"font-weight: 400;\">In the next blog post, we\u2019ll create another &#8220;read&#8221; endpoint. Instead of SQL++, we\u2019ll look at another, faster way that data can be accessed and read.<\/span><\/p>\n<p><span style=\"font-weight: 400;\">In the meantime, you should:<\/span><\/p>\n<ul>\n<li style=\"list-style-type: none;\">\n<ul>\n<li style=\"font-weight: 400;\" aria-level=\"1\"><a href=\"https:\/\/cloud.couchbase.com\/sign-up\/\" target=\"_blank\" rel=\"noopener\"><span style=\"font-weight: 400;\">Sign up for a Capella free-trial<\/span><\/a><\/li>\n<li style=\"font-weight: 400;\" aria-level=\"1\"><span style=\"font-weight: 400;\">Check out the <\/span><a href=\"https:\/\/cloud.couchbase.com\/sign-up\/\" target=\"_blank\" rel=\"noopener\"><span style=\"font-weight: 400;\">Couchbase Playground for .NET<\/span><\/a><span style=\"font-weight: 400;\"> examples that you can run right in the browser.<\/span><\/li>\n<\/ul>\n<\/li>\n<\/ul>\n","protected":false},"excerpt":{"rendered":"<p>CRUD stands for Create, Read, Update, and Delete. In part 2, we\u2019ll look at R for Read, and build an ASP.NET Core endpoint to read data from Couchbase using SQL. Make sure to read part 1 of this series, which [&hellip;]<\/p>\n","protected":false},"author":71,"featured_media":13090,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"_acf_changed":false,"inline_featured_image":false,"footnotes":""},"categories":[1811,10126,10127,1816],"tags":[],"ppma_author":[8937],"class_list":["post-13087","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-dotnet","category-asp-dotnet","category-c-sharp","category-couchbase-server"],"acf":[],"yoast_head":"<!-- This site is optimized with the Yoast SEO Premium plugin v25.7.1 (Yoast SEO v25.7) - https:\/\/yoast.com\/wordpress\/plugins\/seo\/ -->\n<title>ASP.NET Core CRUD with NoSQL: Part 2 - The Couchbase Blog<\/title>\n<meta name=\"description\" content=\"In this post we look at the R in CRUD that stands for Read, and we build an ASP.NET Core endpoint to read data from Couchbase using SQL.\" \/>\n<meta name=\"robots\" content=\"index, follow, max-snippet:-1, max-image-preview:large, max-video-preview:-1\" \/>\n<link rel=\"canonical\" href=\"https:\/\/www.couchbase.com\/blog\/asp-net-crud-nosql-part-2\/\" \/>\n<meta property=\"og:locale\" content=\"en_US\" \/>\n<meta property=\"og:type\" content=\"article\" \/>\n<meta property=\"og:title\" content=\"ASP.NET Core CRUD with NoSQL: Part 2\" \/>\n<meta property=\"og:description\" content=\"In this post we look at the R in CRUD that stands for Read, and we build an ASP.NET Core endpoint to read data from Couchbase using SQL.\" \/>\n<meta property=\"og:url\" content=\"https:\/\/www.couchbase.com\/blog\/asp-net-crud-nosql-part-2\/\" \/>\n<meta property=\"og:site_name\" content=\"The Couchbase Blog\" \/>\n<meta property=\"article:published_time\" content=\"2022-04-18T18:02:34+00:00\" \/>\n<meta property=\"article:modified_time\" content=\"2025-06-14T03:56:46+00:00\" \/>\n<meta property=\"og:image\" content=\"https:\/\/www.couchbase.com\/blog\/wp-content\/uploads\/sites\/1\/2022\/04\/asp-net-couchbase-read-app-part2-scaled.jpg\" \/>\n\t<meta property=\"og:image:width\" content=\"2560\" \/>\n\t<meta property=\"og:image:height\" content=\"1707\" \/>\n\t<meta property=\"og:image:type\" content=\"image\/jpeg\" \/>\n<meta name=\"author\" content=\"Matthew Groves\" \/>\n<meta name=\"twitter:card\" content=\"summary_large_image\" \/>\n<meta name=\"twitter:creator\" content=\"@mgroves\" \/>\n<meta name=\"twitter:label1\" content=\"Written by\" \/>\n\t<meta name=\"twitter:data1\" content=\"Matthew Groves\" \/>\n\t<meta name=\"twitter:label2\" content=\"Est. reading time\" \/>\n\t<meta name=\"twitter:data2\" content=\"4 minutes\" \/>\n<script type=\"application\/ld+json\" class=\"yoast-schema-graph\">{\"@context\":\"https:\/\/schema.org\",\"@graph\":[{\"@type\":\"Article\",\"@id\":\"https:\/\/www.couchbase.com\/blog\/asp-net-crud-nosql-part-2\/#article\",\"isPartOf\":{\"@id\":\"https:\/\/www.couchbase.com\/blog\/asp-net-crud-nosql-part-2\/\"},\"author\":{\"name\":\"Matthew Groves\",\"@id\":\"https:\/\/www.couchbase.com\/blog\/#\/schema\/person\/3929663e372020321b0152dc4fa65a58\"},\"headline\":\"ASP.NET Core CRUD with NoSQL: Part 2\",\"datePublished\":\"2022-04-18T18:02:34+00:00\",\"dateModified\":\"2025-06-14T03:56:46+00:00\",\"mainEntityOfPage\":{\"@id\":\"https:\/\/www.couchbase.com\/blog\/asp-net-crud-nosql-part-2\/\"},\"wordCount\":801,\"commentCount\":0,\"publisher\":{\"@id\":\"https:\/\/www.couchbase.com\/blog\/#organization\"},\"image\":{\"@id\":\"https:\/\/www.couchbase.com\/blog\/asp-net-crud-nosql-part-2\/#primaryimage\"},\"thumbnailUrl\":\"https:\/\/www.couchbase.com\/blog\/wp-content\/uploads\/sites\/1\/2022\/04\/asp-net-couchbase-read-app-part2-scaled.jpg\",\"articleSection\":[\".NET\",\"ASP.NET\",\"C#\",\"Couchbase Server\"],\"inLanguage\":\"en-US\",\"potentialAction\":[{\"@type\":\"CommentAction\",\"name\":\"Comment\",\"target\":[\"https:\/\/www.couchbase.com\/blog\/asp-net-crud-nosql-part-2\/#respond\"]}]},{\"@type\":\"WebPage\",\"@id\":\"https:\/\/www.couchbase.com\/blog\/asp-net-crud-nosql-part-2\/\",\"url\":\"https:\/\/www.couchbase.com\/blog\/asp-net-crud-nosql-part-2\/\",\"name\":\"ASP.NET Core CRUD with NoSQL: Part 2 - The Couchbase Blog\",\"isPartOf\":{\"@id\":\"https:\/\/www.couchbase.com\/blog\/#website\"},\"primaryImageOfPage\":{\"@id\":\"https:\/\/www.couchbase.com\/blog\/asp-net-crud-nosql-part-2\/#primaryimage\"},\"image\":{\"@id\":\"https:\/\/www.couchbase.com\/blog\/asp-net-crud-nosql-part-2\/#primaryimage\"},\"thumbnailUrl\":\"https:\/\/www.couchbase.com\/blog\/wp-content\/uploads\/sites\/1\/2022\/04\/asp-net-couchbase-read-app-part2-scaled.jpg\",\"datePublished\":\"2022-04-18T18:02:34+00:00\",\"dateModified\":\"2025-06-14T03:56:46+00:00\",\"description\":\"In this post we look at the R in CRUD that stands for Read, and we build an ASP.NET Core endpoint to read data from Couchbase using SQL.\",\"breadcrumb\":{\"@id\":\"https:\/\/www.couchbase.com\/blog\/asp-net-crud-nosql-part-2\/#breadcrumb\"},\"inLanguage\":\"en-US\",\"potentialAction\":[{\"@type\":\"ReadAction\",\"target\":[\"https:\/\/www.couchbase.com\/blog\/asp-net-crud-nosql-part-2\/\"]}]},{\"@type\":\"ImageObject\",\"inLanguage\":\"en-US\",\"@id\":\"https:\/\/www.couchbase.com\/blog\/asp-net-crud-nosql-part-2\/#primaryimage\",\"url\":\"https:\/\/www.couchbase.com\/blog\/wp-content\/uploads\/sites\/1\/2022\/04\/asp-net-couchbase-read-app-part2-scaled.jpg\",\"contentUrl\":\"https:\/\/www.couchbase.com\/blog\/wp-content\/uploads\/sites\/1\/2022\/04\/asp-net-couchbase-read-app-part2-scaled.jpg\",\"width\":2560,\"height\":1707,\"caption\":\"ASP.NET app tutorial to read from Couchbase NoSQL\"},{\"@type\":\"BreadcrumbList\",\"@id\":\"https:\/\/www.couchbase.com\/blog\/asp-net-crud-nosql-part-2\/#breadcrumb\",\"itemListElement\":[{\"@type\":\"ListItem\",\"position\":1,\"name\":\"Home\",\"item\":\"https:\/\/www.couchbase.com\/blog\/\"},{\"@type\":\"ListItem\",\"position\":2,\"name\":\"ASP.NET Core CRUD with NoSQL: Part 2\"}]},{\"@type\":\"WebSite\",\"@id\":\"https:\/\/www.couchbase.com\/blog\/#website\",\"url\":\"https:\/\/www.couchbase.com\/blog\/\",\"name\":\"The Couchbase Blog\",\"description\":\"Couchbase, the NoSQL Database\",\"publisher\":{\"@id\":\"https:\/\/www.couchbase.com\/blog\/#organization\"},\"potentialAction\":[{\"@type\":\"SearchAction\",\"target\":{\"@type\":\"EntryPoint\",\"urlTemplate\":\"https:\/\/www.couchbase.com\/blog\/?s={search_term_string}\"},\"query-input\":{\"@type\":\"PropertyValueSpecification\",\"valueRequired\":true,\"valueName\":\"search_term_string\"}}],\"inLanguage\":\"en-US\"},{\"@type\":\"Organization\",\"@id\":\"https:\/\/www.couchbase.com\/blog\/#organization\",\"name\":\"The Couchbase Blog\",\"url\":\"https:\/\/www.couchbase.com\/blog\/\",\"logo\":{\"@type\":\"ImageObject\",\"inLanguage\":\"en-US\",\"@id\":\"https:\/\/www.couchbase.com\/blog\/#\/schema\/logo\/image\/\",\"url\":\"https:\/\/www.couchbase.com\/blog\/wp-content\/uploads\/2023\/04\/admin-logo.png\",\"contentUrl\":\"https:\/\/www.couchbase.com\/blog\/wp-content\/uploads\/2023\/04\/admin-logo.png\",\"width\":218,\"height\":34,\"caption\":\"The Couchbase Blog\"},\"image\":{\"@id\":\"https:\/\/www.couchbase.com\/blog\/#\/schema\/logo\/image\/\"}},{\"@type\":\"Person\",\"@id\":\"https:\/\/www.couchbase.com\/blog\/#\/schema\/person\/3929663e372020321b0152dc4fa65a58\",\"name\":\"Matthew Groves\",\"image\":{\"@type\":\"ImageObject\",\"inLanguage\":\"en-US\",\"@id\":\"https:\/\/www.couchbase.com\/blog\/#\/schema\/person\/image\/ba51e6aacc53995c323a634e4502ef54\",\"url\":\"https:\/\/secure.gravatar.com\/avatar\/70feb1b28a099ad0112b8d21fe1e81e1a4524beed3e20b7f107d5370e85a07ab?s=96&d=mm&r=g\",\"contentUrl\":\"https:\/\/secure.gravatar.com\/avatar\/70feb1b28a099ad0112b8d21fe1e81e1a4524beed3e20b7f107d5370e85a07ab?s=96&d=mm&r=g\",\"caption\":\"Matthew Groves\"},\"description\":\"Matthew D. Groves is a guy who loves to code. It doesn't matter if it's C#, jQuery, or PHP: he'll submit pull requests for anything. He has been coding professionally ever since he wrote a QuickBASIC point-of-sale app for his parent's pizza shop back in the 90s. He currently works as a Senior Product Marketing Manager for Couchbase. His free time is spent with his family, watching the Reds, and getting involved in the developer community. He is the author of AOP in .NET, Pro Microservices in .NET, a Pluralsight author, and a Microsoft MVP.\",\"sameAs\":[\"https:\/\/crosscuttingconcerns.com\",\"https:\/\/x.com\/mgroves\"],\"url\":\"https:\/\/www.couchbase.com\/blog\/author\/matthew-groves\/\"}]}<\/script>\n<!-- \/ Yoast SEO Premium plugin. -->","yoast_head_json":{"title":"ASP.NET Core CRUD with NoSQL: Part 2 - The Couchbase Blog","description":"In this post we look at the R in CRUD that stands for Read, and we build an ASP.NET Core endpoint to read data from Couchbase using SQL.","robots":{"index":"index","follow":"follow","max-snippet":"max-snippet:-1","max-image-preview":"max-image-preview:large","max-video-preview":"max-video-preview:-1"},"canonical":"https:\/\/www.couchbase.com\/blog\/asp-net-crud-nosql-part-2\/","og_locale":"en_US","og_type":"article","og_title":"ASP.NET Core CRUD with NoSQL: Part 2","og_description":"In this post we look at the R in CRUD that stands for Read, and we build an ASP.NET Core endpoint to read data from Couchbase using SQL.","og_url":"https:\/\/www.couchbase.com\/blog\/asp-net-crud-nosql-part-2\/","og_site_name":"The Couchbase Blog","article_published_time":"2022-04-18T18:02:34+00:00","article_modified_time":"2025-06-14T03:56:46+00:00","og_image":[{"width":2560,"height":1707,"url":"https:\/\/www.couchbase.com\/blog\/wp-content\/uploads\/sites\/1\/2022\/04\/asp-net-couchbase-read-app-part2-scaled.jpg","type":"image\/jpeg"}],"author":"Matthew Groves","twitter_card":"summary_large_image","twitter_creator":"@mgroves","twitter_misc":{"Written by":"Matthew Groves","Est. reading time":"4 minutes"},"schema":{"@context":"https:\/\/schema.org","@graph":[{"@type":"Article","@id":"https:\/\/www.couchbase.com\/blog\/asp-net-crud-nosql-part-2\/#article","isPartOf":{"@id":"https:\/\/www.couchbase.com\/blog\/asp-net-crud-nosql-part-2\/"},"author":{"name":"Matthew Groves","@id":"https:\/\/www.couchbase.com\/blog\/#\/schema\/person\/3929663e372020321b0152dc4fa65a58"},"headline":"ASP.NET Core CRUD with NoSQL: Part 2","datePublished":"2022-04-18T18:02:34+00:00","dateModified":"2025-06-14T03:56:46+00:00","mainEntityOfPage":{"@id":"https:\/\/www.couchbase.com\/blog\/asp-net-crud-nosql-part-2\/"},"wordCount":801,"commentCount":0,"publisher":{"@id":"https:\/\/www.couchbase.com\/blog\/#organization"},"image":{"@id":"https:\/\/www.couchbase.com\/blog\/asp-net-crud-nosql-part-2\/#primaryimage"},"thumbnailUrl":"https:\/\/www.couchbase.com\/blog\/wp-content\/uploads\/sites\/1\/2022\/04\/asp-net-couchbase-read-app-part2-scaled.jpg","articleSection":[".NET","ASP.NET","C#","Couchbase Server"],"inLanguage":"en-US","potentialAction":[{"@type":"CommentAction","name":"Comment","target":["https:\/\/www.couchbase.com\/blog\/asp-net-crud-nosql-part-2\/#respond"]}]},{"@type":"WebPage","@id":"https:\/\/www.couchbase.com\/blog\/asp-net-crud-nosql-part-2\/","url":"https:\/\/www.couchbase.com\/blog\/asp-net-crud-nosql-part-2\/","name":"ASP.NET Core CRUD with NoSQL: Part 2 - The Couchbase Blog","isPartOf":{"@id":"https:\/\/www.couchbase.com\/blog\/#website"},"primaryImageOfPage":{"@id":"https:\/\/www.couchbase.com\/blog\/asp-net-crud-nosql-part-2\/#primaryimage"},"image":{"@id":"https:\/\/www.couchbase.com\/blog\/asp-net-crud-nosql-part-2\/#primaryimage"},"thumbnailUrl":"https:\/\/www.couchbase.com\/blog\/wp-content\/uploads\/sites\/1\/2022\/04\/asp-net-couchbase-read-app-part2-scaled.jpg","datePublished":"2022-04-18T18:02:34+00:00","dateModified":"2025-06-14T03:56:46+00:00","description":"In this post we look at the R in CRUD that stands for Read, and we build an ASP.NET Core endpoint to read data from Couchbase using SQL.","breadcrumb":{"@id":"https:\/\/www.couchbase.com\/blog\/asp-net-crud-nosql-part-2\/#breadcrumb"},"inLanguage":"en-US","potentialAction":[{"@type":"ReadAction","target":["https:\/\/www.couchbase.com\/blog\/asp-net-crud-nosql-part-2\/"]}]},{"@type":"ImageObject","inLanguage":"en-US","@id":"https:\/\/www.couchbase.com\/blog\/asp-net-crud-nosql-part-2\/#primaryimage","url":"https:\/\/www.couchbase.com\/blog\/wp-content\/uploads\/sites\/1\/2022\/04\/asp-net-couchbase-read-app-part2-scaled.jpg","contentUrl":"https:\/\/www.couchbase.com\/blog\/wp-content\/uploads\/sites\/1\/2022\/04\/asp-net-couchbase-read-app-part2-scaled.jpg","width":2560,"height":1707,"caption":"ASP.NET app tutorial to read from Couchbase NoSQL"},{"@type":"BreadcrumbList","@id":"https:\/\/www.couchbase.com\/blog\/asp-net-crud-nosql-part-2\/#breadcrumb","itemListElement":[{"@type":"ListItem","position":1,"name":"Home","item":"https:\/\/www.couchbase.com\/blog\/"},{"@type":"ListItem","position":2,"name":"ASP.NET Core CRUD with NoSQL: Part 2"}]},{"@type":"WebSite","@id":"https:\/\/www.couchbase.com\/blog\/#website","url":"https:\/\/www.couchbase.com\/blog\/","name":"The Couchbase Blog","description":"Couchbase, the NoSQL Database","publisher":{"@id":"https:\/\/www.couchbase.com\/blog\/#organization"},"potentialAction":[{"@type":"SearchAction","target":{"@type":"EntryPoint","urlTemplate":"https:\/\/www.couchbase.com\/blog\/?s={search_term_string}"},"query-input":{"@type":"PropertyValueSpecification","valueRequired":true,"valueName":"search_term_string"}}],"inLanguage":"en-US"},{"@type":"Organization","@id":"https:\/\/www.couchbase.com\/blog\/#organization","name":"The Couchbase Blog","url":"https:\/\/www.couchbase.com\/blog\/","logo":{"@type":"ImageObject","inLanguage":"en-US","@id":"https:\/\/www.couchbase.com\/blog\/#\/schema\/logo\/image\/","url":"https:\/\/www.couchbase.com\/blog\/wp-content\/uploads\/2023\/04\/admin-logo.png","contentUrl":"https:\/\/www.couchbase.com\/blog\/wp-content\/uploads\/2023\/04\/admin-logo.png","width":218,"height":34,"caption":"The Couchbase Blog"},"image":{"@id":"https:\/\/www.couchbase.com\/blog\/#\/schema\/logo\/image\/"}},{"@type":"Person","@id":"https:\/\/www.couchbase.com\/blog\/#\/schema\/person\/3929663e372020321b0152dc4fa65a58","name":"Matthew Groves","image":{"@type":"ImageObject","inLanguage":"en-US","@id":"https:\/\/www.couchbase.com\/blog\/#\/schema\/person\/image\/ba51e6aacc53995c323a634e4502ef54","url":"https:\/\/secure.gravatar.com\/avatar\/70feb1b28a099ad0112b8d21fe1e81e1a4524beed3e20b7f107d5370e85a07ab?s=96&d=mm&r=g","contentUrl":"https:\/\/secure.gravatar.com\/avatar\/70feb1b28a099ad0112b8d21fe1e81e1a4524beed3e20b7f107d5370e85a07ab?s=96&d=mm&r=g","caption":"Matthew Groves"},"description":"Matthew D. Groves is a guy who loves to code. It doesn't matter if it's C#, jQuery, or PHP: he'll submit pull requests for anything. He has been coding professionally ever since he wrote a QuickBASIC point-of-sale app for his parent's pizza shop back in the 90s. He currently works as a Senior Product Marketing Manager for Couchbase. His free time is spent with his family, watching the Reds, and getting involved in the developer community. He is the author of AOP in .NET, Pro Microservices in .NET, a Pluralsight author, and a Microsoft MVP.","sameAs":["https:\/\/crosscuttingconcerns.com","https:\/\/x.com\/mgroves"],"url":"https:\/\/www.couchbase.com\/blog\/author\/matthew-groves\/"}]}},"authors":[{"term_id":8937,"user_id":71,"is_guest":0,"slug":"matthew-groves","display_name":"Matthew Groves","avatar_url":"https:\/\/secure.gravatar.com\/avatar\/70feb1b28a099ad0112b8d21fe1e81e1a4524beed3e20b7f107d5370e85a07ab?s=96&d=mm&r=g","author_category":"","last_name":"Groves","first_name":"Matthew","job_title":"","user_url":"https:\/\/crosscuttingconcerns.com","description":"Matthew D. Groves is a guy who loves to code.  It doesn't matter if it's C#, jQuery, or PHP: he'll submit pull requests for anything.  He has been coding professionally ever since he wrote a QuickBASIC point-of-sale app for his parent's pizza shop back in the 90s.  He currently works as a Senior Product Marketing Manager for Couchbase. His free time is spent with his family, watching the Reds, and getting involved in the developer community.  He is the author of AOP in .NET, Pro Microservices in .NET, a Pluralsight author, and a Microsoft MVP."}],"_links":{"self":[{"href":"https:\/\/www.couchbase.com\/blog\/wp-json\/wp\/v2\/posts\/13087","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/www.couchbase.com\/blog\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/www.couchbase.com\/blog\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/www.couchbase.com\/blog\/wp-json\/wp\/v2\/users\/71"}],"replies":[{"embeddable":true,"href":"https:\/\/www.couchbase.com\/blog\/wp-json\/wp\/v2\/comments?post=13087"}],"version-history":[{"count":0,"href":"https:\/\/www.couchbase.com\/blog\/wp-json\/wp\/v2\/posts\/13087\/revisions"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/www.couchbase.com\/blog\/wp-json\/wp\/v2\/media\/13090"}],"wp:attachment":[{"href":"https:\/\/www.couchbase.com\/blog\/wp-json\/wp\/v2\/media?parent=13087"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/www.couchbase.com\/blog\/wp-json\/wp\/v2\/categories?post=13087"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/www.couchbase.com\/blog\/wp-json\/wp\/v2\/tags?post=13087"},{"taxonomy":"author","embeddable":true,"href":"https:\/\/www.couchbase.com\/blog\/wp-json\/wp\/v2\/ppma_author?post=13087"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}