{"id":765,"date":"2015-12-03T09:27:55","date_gmt":"2015-12-03T08:27:55","guid":{"rendered":"https:\/\/sii.pl\/blog\/?p=765"},"modified":"2023-07-20T14:17:51","modified_gmt":"2023-07-20T12:17:51","slug":"cassandra-with-c-fluent-query-builder","status":"publish","type":"post","link":"https:\/\/sii.pl\/blog\/en\/cassandra-with-c-fluent-query-builder\/","title":{"rendered":"Cassandra with C# Fluent Query Builder"},"content":{"rendered":"\n<p>Cassandra is a popular NoSql database technology which allows an easy configuration of many instances (nodes) providing high scalability and performance. To start work, visit <a href=\"http:\/\/www.planetcassandra.org\/cassandra\/\" target=\"_blank\" rel=\"noopener\" rel=\"nofollow\" >planet cassandra<\/a>\u00a0to get the community edition or use directly UNIX command prompt following <a href=\"http:\/\/piotrluksza.com\/2015\/11\/27\/installing-cassandra-on-linux-ubuntu\/\" title=\"Piotr \u0141uksza Gosu Code - C#, .NET Programming Blog - Installing Cassandra on Linux \u2013 Ubuntu\" rel=\"nofollow\" >Installing Cassandra on Ubuntu<\/a>.<br>There is a driver that lets you work with .NET technology with C# syntax wery well, just download the nuget package using command prompt &#8220;Install-Package CassandraCSharpDriver&#8221; or use the GUI version:<\/p>\n\n\n\n<figure class=\"wp-block-image aligncenter\"><a href=\"https:\/\/sii.pl\/blog\/wp-content\/uploads\/2015\/11\/nuget.png\"><img decoding=\"async\" width=\"1024\" height=\"579\" src=\"https:\/\/sii.pl\/blog\/wp-content\/uploads\/2015\/11\/nuget-1024x579.png\" alt=\"Download Cassandra c# Driver from nuget\" class=\"wp-image-815\" srcset=\"https:\/\/sii.pl\/blog\/wp-content\/uploads\/2015\/11\/nuget-1024x579.png 1024w, https:\/\/sii.pl\/blog\/wp-content\/uploads\/2015\/11\/nuget-300x170.png 300w, https:\/\/sii.pl\/blog\/wp-content\/uploads\/2015\/11\/nuget.png 1313w\" sizes=\"(max-width: 1024px) 100vw, 1024px\" \/><\/a><\/figure>\n\n\n\n<p><\/p>\n\n\n\n<p><a href=\"https:\/\/academy.datastax.com\/downloads\/ops-center#devCenter\" target=\"_blank\" rel=\"noopener\" rel=\"nofollow\" >DevCenter<\/a>&nbsp;is worth checking, this tool allows a user to create and run Cassandra Query Language (<a href=\"http:\/\/cassandra.apache.org\/doc\/cql3\/CQL.html\" target=\"_blank\" rel=\"noopener\" rel=\"nofollow\" >CQL<\/a>) against Apache Cassandra. It&#8217;s&nbsp;similiar to MS ManagementTools, but unfortunately the free version is very poor.<\/p>\n\n\n\n<p>In this article I am not going to focus on Cassandra database engine itself, but how to use it from .NET Framework, so it&#8217;s dedicated to .NET Developers.&nbsp; I&#8217;ve chosen a <strong>fluent interface builder pattern<\/strong> to encapsulate the logic of a <a href=\"http:\/\/docs.datastax.com\/en\/cql\/3.1\/cql\/cql_reference\/batch_r.html\" target=\"_blank\" rel=\"noopener\" rel=\"nofollow\" >batch <\/a>statement (Insert, Update, Delete) that combines multiple data operations into one logical and atomic statement.<\/p>\n\n\n\n<p>Firstly, let&#8217;s set up a keyspace and create a session<\/p>\n\n\n<div class=\"wp-block-syntaxhighlighter-code \"><pre class=\"brush: csharp; title: ; notranslate\" title=\"\">\nvar builder = Cluster\n.Builder()\n.AddContactPoint(\"127.0.0.1\")\n.WithQueryOptions(new QueryOptions().SetConsistencyLevel(ConsistencyLevel.One))\n.WithLoadBalancingPolicy(new RoundRobinPolicy())\n.WithDefaultKeyspace(\"Cassandra_Demo\");\n \nvar cluster = builder.Build();\n_session = cluster.ConnectAndCreateDefaultKeyspaceIfNotExists();\n<\/pre><\/div>\n\n\n<p>Now we&#8217;re ready to put together C# and Cassandra so, let&#8217;s write a method to create a simple User table:<\/p>\n\n\n<div class=\"wp-block-syntaxhighlighter-code \"><pre class=\"brush: csharp; title: ; notranslate\" title=\"\">\npublic static void CreateUserTableIfNotExists(ISession session)\n{\nsession.Execute(\"CREATE TABLE IF NOT EXISTS User (\nid UUID PRIMARY KEY,\nfirstname varchar,\nlastname varchar,\ncountry varchar,\nisactive boolean);\"\n);\n}\n<\/pre><\/div>\n\n\n<p>To populate our table with some data, I am going to create a query using fluent api, the builder class can set up multiple parameters and takes the following form<\/p>\n\n\n<div class=\"wp-block-syntaxhighlighter-code \"><pre class=\"brush: csharp; title: ; notranslate\" title=\"\">\npublic class GenerateUsersQueryBuilder : QueryBuilderBase\n{\nprivate int _limit;\nprivate string _country;\nBatchType _batchType = BatchType.Unlogged;\n\npublic GenerateUsersQueryBuilder SetLimit(int limit)\n{\n_limit = limit;\nreturn this;\n}\npublic GenerateUsersQueryBuilder SetBatchType(BatchType batchType)\n{\n_batchType = batchType;\nreturn this;\n}\n\npublic GenerateUsersQueryBuilder FromCountry(string country)\n{\n_country = country;\nreturn this;\n}\n\npublic override CassandraQuery Build()\n{\nvar sb = new StringBuilder();\nsb.AppendLine(&quot;BEGIN &quot; + (_batchType == BatchType.Counter ?\n&quot;COUNTER &quot; : &quot;UNLOGGED &quot;) + &quot;BATCH&quot;);\n\nfor (int i = 0; i &lt; _limit; i++)\n{\nsb.AppendLine(string.Format(\n&quot;INSERT INTO user (id, firstname, lastname, country, isactive) VALUES\n({0}, &#039;{1}&#039;, &#039;{2}&#039;, &#039;{3}&#039;, {4})&quot;,\nGuid.NewGuid(),\nstring.Format(&quot;FirstName{0}&quot;, i + 1),\nstring.Format(&quot;LastName{0}&quot;, i + 1),\n_country,\ni % 2 == 0));\nsb.AppendLine(&quot;;&quot;);\n}\n\nsb.Append(&quot;APPLY BATCH&quot;);\n\nreturn new CassandraQuery() { Text = sb.ToString() };\n}\n}\n<\/pre><\/div>\n\n\n<p>Now we are able to create and populate the table with the following code<\/p>\n\n\n<div class=\"wp-block-syntaxhighlighter-code \"><pre class=\"brush: csharp; title: ; notranslate\" title=\"\">\nQueryTools.CreateUserTableIfNotExists(_session);\n\nCassandraQuery query = new GenerateUsersQueryBuilder().FromCountry(\"Canada\")\n.SetLimit(_limit).SetBatchType(BatchType.Unlogged)\n.Build();\n\n_session.Execute(query.Text);\n<\/pre><\/div>\n\n\n<p>Of course later on, we want to fetch and display results in the output programmatically, so I created some helper method to map data from the rowset into domain model<\/p>\n\n\n<div class=\"wp-block-syntaxhighlighter-code \"><pre class=\"brush: csharp; title: ; notranslate\" title=\"\">\nRowSet rsUsers = _session.Execute(string.Format(&quot;SELECT * FROM user LIMIT {0}&quot;, _limit));\n \nvar users = new List&lt;UserModel&gt;();\nforeach (var userRow in rsUsers)\n{\nusers.Add(ReflectionTools.GetSingleEntryDynamicFromReader&lt;UserModel&gt;(userRow));\n}\n \nforeach (UserModel user in users)\n{\nConsole.WriteLine(&quot;{0} {1} {2} {3} {4}&quot;,\nuser.Id, user.FirstName, user.LastName, user.Country, user.IsActive);\n}\n<\/pre><\/div>\n\n\n<p>As we see, the code works well<\/p>\n\n\n\n<figure class=\"wp-block-image aligncenter\"><a href=\"https:\/\/sii.pl\/blog\/wp-content\/uploads\/2015\/11\/fluent-builder-output.png\"><img decoding=\"async\" width=\"834\" height=\"539\" src=\"https:\/\/sii.pl\/blog\/wp-content\/uploads\/2015\/11\/fluent-builder-output.png\" alt=\"fluent builder output\" class=\"wp-image-830\" srcset=\"https:\/\/sii.pl\/blog\/wp-content\/uploads\/2015\/11\/fluent-builder-output.png 834w, https:\/\/sii.pl\/blog\/wp-content\/uploads\/2015\/11\/fluent-builder-output-300x194.png 300w\" sizes=\"(max-width: 834px) 100vw, 834px\" \/><\/a><\/figure>\n\n\n\n<p>Full source code from this article is avaliable <a href=\"https:\/\/onedrive.live.com\/download?resid=A9069B07DB1D7693!4462&amp;authkey=!ABoaE7_jT-pBI1M&amp;ithint=file%2czip\" rel=\"nofollow\" >here<\/a>.<\/p>\n\n\n<div class=\"kk-star-ratings kksr-auto kksr-align-left kksr-valign-bottom\"\n    data-payload='{&quot;align&quot;:&quot;left&quot;,&quot;id&quot;:&quot;765&quot;,&quot;slug&quot;:&quot;default&quot;,&quot;valign&quot;:&quot;bottom&quot;,&quot;ignore&quot;:&quot;&quot;,&quot;reference&quot;:&quot;auto&quot;,&quot;class&quot;:&quot;&quot;,&quot;count&quot;:&quot;2&quot;,&quot;legendonly&quot;:&quot;&quot;,&quot;readonly&quot;:&quot;&quot;,&quot;score&quot;:&quot;5&quot;,&quot;starsonly&quot;:&quot;&quot;,&quot;best&quot;:&quot;5&quot;,&quot;gap&quot;:&quot;11&quot;,&quot;greet&quot;:&quot;&quot;,&quot;legend&quot;:&quot;5\\\/5 ( votes: 2)&quot;,&quot;size&quot;:&quot;18&quot;,&quot;title&quot;:&quot;Cassandra with C# Fluent Query Builder&quot;,&quot;width&quot;:&quot;139.5&quot;,&quot;_legend&quot;:&quot;{score}\\\/{best} ( {votes}: {count})&quot;,&quot;font_factor&quot;:&quot;1.25&quot;}'>\n            \n<div class=\"kksr-stars\">\n    \n<div class=\"kksr-stars-inactive\">\n            <div class=\"kksr-star\" data-star=\"1\" style=\"padding-right: 11px\">\n            \n\n<div class=\"kksr-icon\" style=\"width: 18px; height: 18px;\"><\/div>\n        <\/div>\n            <div class=\"kksr-star\" data-star=\"2\" style=\"padding-right: 11px\">\n            \n\n<div class=\"kksr-icon\" style=\"width: 18px; height: 18px;\"><\/div>\n        <\/div>\n            <div class=\"kksr-star\" data-star=\"3\" style=\"padding-right: 11px\">\n            \n\n<div class=\"kksr-icon\" style=\"width: 18px; height: 18px;\"><\/div>\n        <\/div>\n            <div class=\"kksr-star\" data-star=\"4\" style=\"padding-right: 11px\">\n            \n\n<div class=\"kksr-icon\" style=\"width: 18px; height: 18px;\"><\/div>\n        <\/div>\n            <div class=\"kksr-star\" data-star=\"5\" style=\"padding-right: 11px\">\n            \n\n<div class=\"kksr-icon\" style=\"width: 18px; height: 18px;\"><\/div>\n        <\/div>\n    <\/div>\n    \n<div class=\"kksr-stars-active\" style=\"width: 139.5px;\">\n            <div class=\"kksr-star\" style=\"padding-right: 11px\">\n            \n\n<div class=\"kksr-icon\" style=\"width: 18px; height: 18px;\"><\/div>\n        <\/div>\n            <div class=\"kksr-star\" style=\"padding-right: 11px\">\n            \n\n<div class=\"kksr-icon\" style=\"width: 18px; height: 18px;\"><\/div>\n        <\/div>\n            <div class=\"kksr-star\" style=\"padding-right: 11px\">\n            \n\n<div class=\"kksr-icon\" style=\"width: 18px; height: 18px;\"><\/div>\n        <\/div>\n            <div class=\"kksr-star\" style=\"padding-right: 11px\">\n            \n\n<div class=\"kksr-icon\" style=\"width: 18px; height: 18px;\"><\/div>\n        <\/div>\n            <div class=\"kksr-star\" style=\"padding-right: 11px\">\n            \n\n<div class=\"kksr-icon\" style=\"width: 18px; height: 18px;\"><\/div>\n        <\/div>\n    <\/div>\n<\/div>\n                \n\n<div class=\"kksr-legend\" style=\"font-size: 14.4px;\">\n            5\/5 ( votes: 2)    <\/div>\n    <\/div>\n","protected":false},"excerpt":{"rendered":"<p>Cassandra is a popular NoSql database technology which allows an easy configuration of many instances (nodes) providing high scalability and &hellip; <a class=\"continued-btn\" href=\"https:\/\/sii.pl\/blog\/en\/cassandra-with-c-fluent-query-builder\/\">Continued<\/a><\/p>\n","protected":false},"author":3,"featured_media":1140,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"_acf_changed":false,"_editorskit_title_hidden":false,"_editorskit_reading_time":0,"_editorskit_is_block_options_detached":false,"_editorskit_block_options_position":"{}","inline_featured_image":false,"footnotes":""},"categories":[1320],"tags":[1425,1488,1489,1490],"class_list":["post-765","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-hard-development","tag-c-en","tag-cassandra-en","tag-cql-en","tag-datastax-en"],"acf":[],"aioseo_notices":[],"republish_history":[],"featured_media_url":"https:\/\/sii.pl\/blog\/wp-content\/uploads\/2015\/12\/20_Cassandra_v2.jpg","category_names":["Hard development"],"_links":{"self":[{"href":"https:\/\/sii.pl\/blog\/en\/wp-json\/wp\/v2\/posts\/765"}],"collection":[{"href":"https:\/\/sii.pl\/blog\/en\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/sii.pl\/blog\/en\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/sii.pl\/blog\/en\/wp-json\/wp\/v2\/users\/3"}],"replies":[{"embeddable":true,"href":"https:\/\/sii.pl\/blog\/en\/wp-json\/wp\/v2\/comments?post=765"}],"version-history":[{"count":2,"href":"https:\/\/sii.pl\/blog\/en\/wp-json\/wp\/v2\/posts\/765\/revisions"}],"predecessor-version":[{"id":23000,"href":"https:\/\/sii.pl\/blog\/en\/wp-json\/wp\/v2\/posts\/765\/revisions\/23000"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/sii.pl\/blog\/en\/wp-json\/wp\/v2\/media\/1140"}],"wp:attachment":[{"href":"https:\/\/sii.pl\/blog\/en\/wp-json\/wp\/v2\/media?parent=765"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/sii.pl\/blog\/en\/wp-json\/wp\/v2\/categories?post=765"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/sii.pl\/blog\/en\/wp-json\/wp\/v2\/tags?post=765"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}