<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:dc="http://purl.org/dc/elements/1.1/">
  <channel>
    <title>DEV Community: Giorgi Anakidze</title>
    <description>The latest articles on DEV Community by Giorgi Anakidze (@gpskwlkr).</description>
    <link>https://dev.to/gpskwlkr</link>
    <image>
      <url>https://media2.dev.to/dynamic/image/width=90,height=90,fit=cover,gravity=auto,format=auto/https:%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F465295%2F35a1d652-9263-47b2-8941-464392685e05.JPG</url>
      <title>DEV Community: Giorgi Anakidze</title>
      <link>https://dev.to/gpskwlkr</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/gpskwlkr"/>
    <language>en</language>
    <item>
      <title>Stop Guessing, Start Measuring: Transform Your Code with BenchmarkDotnet!</title>
      <dc:creator>Giorgi Anakidze</dc:creator>
      <pubDate>Tue, 13 Feb 2024 14:09:51 +0000</pubDate>
      <link>https://dev.to/gpskwlkr/stop-guessing-start-measuring-transform-your-code-with-benchmarkdotnet-49af</link>
      <guid>https://dev.to/gpskwlkr/stop-guessing-start-measuring-transform-your-code-with-benchmarkdotnet-49af</guid>
      <description>&lt;p&gt;Imagine perfecting your .NET application only to struggle with performance measurement. BenchmarkDotnet resolves this, offering developers a streamlined solution for precise benchmarking. Are you in your way to migrating the project from .NET 5 to .NET 8? Is it really worth it? BenchmarkDotnet allows you to test your most time or memory consuming methods against multiple versions of .NET framework with ease and decide whether you really should do it.&lt;/p&gt;

&lt;h1&gt;
  
  
  Demystifying BenchmarkDotnet
&lt;/h1&gt;

&lt;p&gt;Let’s look at the first example you see, when you open up BenchmarkDotnet’s &lt;a href="https://benchmarkdotnet.org"&gt;website&lt;/a&gt;, or &lt;a href="https://github.com/dotnet/BenchmarkDotNet"&gt;Github&lt;/a&gt; page.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight csharp"&gt;&lt;code&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nf"&gt;SimpleJob&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;RuntimeMoniker&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Net472&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;baseline&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="k"&gt;true&lt;/span&gt;&lt;span class="p"&gt;)]&lt;/span&gt;
&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nf"&gt;SimpleJob&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;RuntimeMoniker&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;NetCoreApp30&lt;/span&gt;&lt;span class="p"&gt;)]&lt;/span&gt;
&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nf"&gt;SimpleJob&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;RuntimeMoniker&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;NativeAot70&lt;/span&gt;&lt;span class="p"&gt;)]&lt;/span&gt;
&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nf"&gt;SimpleJob&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;RuntimeMoniker&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Mono&lt;/span&gt;&lt;span class="p"&gt;)]&lt;/span&gt;
&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;RPlotExporter&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;
&lt;span class="k"&gt;public&lt;/span&gt; &lt;span class="k"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;Md5VsSha256&lt;/span&gt;
&lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;private&lt;/span&gt; &lt;span class="n"&gt;SHA256&lt;/span&gt; &lt;span class="n"&gt;sha256&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="n"&gt;SHA256&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;Create&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
    &lt;span class="k"&gt;private&lt;/span&gt; &lt;span class="n"&gt;MD5&lt;/span&gt; &lt;span class="n"&gt;md5&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="n"&gt;MD5&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;Create&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
    &lt;span class="k"&gt;private&lt;/span&gt; &lt;span class="kt"&gt;byte&lt;/span&gt;&lt;span class="p"&gt;[]&lt;/span&gt; &lt;span class="n"&gt;data&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

    &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nf"&gt;Params&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="m"&gt;1000&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="m"&gt;10000&lt;/span&gt;&lt;span class="p"&gt;)]&lt;/span&gt;
    &lt;span class="k"&gt;public&lt;/span&gt; &lt;span class="kt"&gt;int&lt;/span&gt; &lt;span class="n"&gt;N&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

    &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;GlobalSetup&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;
    &lt;span class="k"&gt;public&lt;/span&gt; &lt;span class="k"&gt;void&lt;/span&gt; &lt;span class="nf"&gt;Setup&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
    &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="n"&gt;data&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="kt"&gt;byte&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;N&lt;/span&gt;&lt;span class="p"&gt;];&lt;/span&gt;
        &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nf"&gt;Random&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="m"&gt;42&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="nf"&gt;NextBytes&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;data&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;

    &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;Benchmark&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;
    &lt;span class="k"&gt;public&lt;/span&gt; &lt;span class="kt"&gt;byte&lt;/span&gt;&lt;span class="p"&gt;[]&lt;/span&gt; &lt;span class="nf"&gt;Sha256&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;sha256&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;ComputeHash&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;data&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

    &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;Benchmark&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;
    &lt;span class="k"&gt;public&lt;/span&gt; &lt;span class="kt"&gt;byte&lt;/span&gt;&lt;span class="p"&gt;[]&lt;/span&gt; &lt;span class="nf"&gt;Md5&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;md5&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;ComputeHash&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;data&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;It’s not required for you to understand everything right now, BenchmarkDotnet has beautiful docs and you could dive straight into it after reading this article, but there are some key concepts that you should understand while using BenchmarkDotnet.&lt;/p&gt;

&lt;h2&gt;
  
  
  1. Targeting multiple versions
&lt;/h2&gt;

&lt;p&gt;With BenchmarkDotnet you can easily test your code against multiple versions of .NET and all you have to do is using an attribute just as we saw in the example above.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight csharp"&gt;&lt;code&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nf"&gt;SimpleJob&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;RuntimeMoniker&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Net472&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;baseline&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="k"&gt;true&lt;/span&gt;&lt;span class="p"&gt;)]&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;You could use as much of these as you want, you’re not really restricted, but it is mandatory that only one of them has &lt;code&gt;baseline: true&lt;/code&gt; flag, it shouldn’t be more than that, but it shouldn’t be none as well, if you’re targeting multiple versions of .NET framework.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Remember! It’s &lt;strong&gt;crucial&lt;/strong&gt; to have all target versions of .NET installed on your system.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;h2&gt;
  
  
  2. Moving setup away from benchmarks
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;While making benchmarks, your code may require some additional data to work with and you typically don’t want to have the data generating process inside of your benchmarks, because then it counts as method execution time, which may not be true in all cases. BenchmarkDotnet solves this problem in an elegant way, you just have to make a method for data generation purposes and mark it as &lt;code&gt;[GlobalSetup]&lt;/code&gt;.
&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight csharp"&gt;&lt;code&gt;    &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;GlobalSetup&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;
    &lt;span class="k"&gt;public&lt;/span&gt; &lt;span class="k"&gt;void&lt;/span&gt; &lt;span class="nf"&gt;Setup&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
    &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="n"&gt;data&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="kt"&gt;byte&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;N&lt;/span&gt;&lt;span class="p"&gt;];&lt;/span&gt;
        &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nf"&gt;Random&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="m"&gt;42&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="nf"&gt;NextBytes&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;data&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ul&gt;
&lt;li&gt;If your benchmarks have more specific needs, you could make a setup method for one benchmark only, which will be executed before the exact benchmark you specify, so it doesn’t slow down other ones.
&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight csharp"&gt;&lt;code&gt;    &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nf"&gt;GlobalSetup&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;Target&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="k"&gt;nameof&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;Sha256&lt;/span&gt;&lt;span class="p"&gt;))]&lt;/span&gt;
    &lt;span class="k"&gt;public&lt;/span&gt; &lt;span class="k"&gt;void&lt;/span&gt; &lt;span class="nf"&gt;Setup&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
    &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="n"&gt;data&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="kt"&gt;byte&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;N&lt;/span&gt;&lt;span class="p"&gt;];&lt;/span&gt;
        &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nf"&gt;Random&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="m"&gt;42&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="nf"&gt;NextBytes&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;data&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ul&gt;
&lt;li&gt;If multiple benchmarks share the same data generation process, you don’t need separate setups for them, you can easily target &lt;strong&gt;multiple&lt;/strong&gt; benchmarks as well.
&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight csharp"&gt;&lt;code&gt;    &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nf"&gt;GlobalSetup&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;Target&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt;&lt;span class="p"&gt;[]&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="k"&gt;nameof&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;Sha256&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt; &lt;span class="k"&gt;nameof&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;Md5&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;})]&lt;/span&gt;
    &lt;span class="k"&gt;public&lt;/span&gt; &lt;span class="k"&gt;void&lt;/span&gt; &lt;span class="nf"&gt;Setup&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
    &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="n"&gt;data&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="kt"&gt;byte&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;N&lt;/span&gt;&lt;span class="p"&gt;];&lt;/span&gt;
        &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nf"&gt;Random&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="m"&gt;42&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="nf"&gt;NextBytes&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;data&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  3. Identifying methods to be benchmarked
&lt;/h2&gt;

&lt;p&gt;Even though the code we're currently examining is relatively straightforward, benchmarks can often involve significant amounts of code, depending on the task at hand. With this in mind, you might have multiple setup methods, helper methods, etc, so it’s crucial to mark which methods need to be benchmarked exactly. The way BenchmarkDotnet does this is pretty straightforward, with the &lt;code&gt;[Benchmark]&lt;/code&gt; attribute. One thing that the code above doesn’t tell you, this attribute can also have a &lt;code&gt;Baseline&lt;/code&gt; parameter. Let’s say you’re refactoring some of the old code and you want to see how the new version compares to it, it’s pretty easy as well.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight csharp"&gt;&lt;code&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nf"&gt;Benchmark&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;Baseline&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="k"&gt;true&lt;/span&gt;&lt;span class="p"&gt;)]&lt;/span&gt;
&lt;span class="k"&gt;public&lt;/span&gt; &lt;span class="k"&gt;void&lt;/span&gt; &lt;span class="nf"&gt;OldVersionCode&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="c1"&gt;// Your old code...&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;Benchmark&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;
&lt;span class="k"&gt;public&lt;/span&gt; &lt;span class="k"&gt;void&lt;/span&gt; &lt;span class="nf"&gt;NewVersionCode&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="c1"&gt;// Your new code...&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="k"&gt;public&lt;/span&gt; &lt;span class="k"&gt;void&lt;/span&gt; &lt;span class="nf"&gt;SomeHelperMethod&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="c1"&gt;// Your helper method code...&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Now with all the other data including mean time, etc, you will also get a new column called &lt;strong&gt;Ratio&lt;/strong&gt; that indicates how your other benchmarks compare to your baseline benchmark. You can see more in the BenchmarkDotnet &lt;a href="https://benchmarkdotnet.org/articles/samples/IntroBenchmarkBaseline.html"&gt;docs&lt;/a&gt; for this parameter.&lt;/p&gt;

&lt;h1&gt;
  
  
  Creating your own benchmarks
&lt;/h1&gt;

&lt;p&gt;Now that we’ve deep dived into BenchmarkDotnet, I think it’s time to run your first benchmark, you could use the same code provided by the docs, or write your own. For the sake of simplicity I’ll cover the one provided.&lt;/p&gt;

&lt;h2&gt;
  
  
  Installing prerequisites
&lt;/h2&gt;

&lt;p&gt;First thing you would want to do, to avoid writing all the code by yourself is installing BenchmarkDotnet templates which could be done via dotnet CLI.&lt;/p&gt;

&lt;p&gt;&lt;code&gt;dotnet new install BenchmarkDotNet.Templates&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;After it’s done, you could create your first benchmark from the CLI via&lt;/p&gt;

&lt;p&gt;&lt;code&gt;dotnet new benchmark&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;Or if you’re using a language different from C#, you could specify it as well&lt;/p&gt;

&lt;p&gt;&lt;code&gt;dotnet new benchmark -lang F#&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;&lt;code&gt;dotnet new benchmark -lang VB&lt;/code&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Running your benchmarks
&lt;/h2&gt;

&lt;p&gt;First thing you see after creating a benchmark project is a default &lt;code&gt;Program&lt;/code&gt; and &lt;code&gt;Benchmarks&lt;/code&gt; classes. &lt;code&gt;Program&lt;/code&gt; is responsible for running benchmarks located at &lt;code&gt;Benchmarks&lt;/code&gt; class. You could have as many benchmark classes as you want, but make sure to add all of them to &lt;code&gt;Program&lt;/code&gt; if you’d like to run them as well. You could see that program contains pretty simple code&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight csharp"&gt;&lt;code&gt; &lt;span class="k"&gt;public&lt;/span&gt; &lt;span class="k"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;Program&lt;/span&gt;
    &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="k"&gt;public&lt;/span&gt; &lt;span class="k"&gt;static&lt;/span&gt; &lt;span class="k"&gt;void&lt;/span&gt; &lt;span class="nf"&gt;Main&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kt"&gt;string&lt;/span&gt;&lt;span class="p"&gt;[]&lt;/span&gt; &lt;span class="n"&gt;args&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
        &lt;span class="p"&gt;{&lt;/span&gt;
            &lt;span class="kt"&gt;var&lt;/span&gt; &lt;span class="n"&gt;config&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="n"&gt;DefaultConfig&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Instance&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
            &lt;span class="kt"&gt;var&lt;/span&gt; &lt;span class="n"&gt;summary&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="n"&gt;BenchmarkRunner&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Run&lt;/span&gt;&lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;Benchmarks&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;(&lt;/span&gt;&lt;span class="n"&gt;config&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;args&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

            &lt;span class="c1"&gt;// Use this to select benchmarks from the console:&lt;/span&gt;
            &lt;span class="c1"&gt;// var summaries = BenchmarkSwitcher.FromAssembly(typeof(Program).Assembly).Run(args, config);&lt;/span&gt;
        &lt;span class="p"&gt;}&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Now if you have multiple benchmark classes and you only want to run several of them you could choose which ones to run with a slight change to your &lt;code&gt;Main&lt;/code&gt; method.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight csharp"&gt;&lt;code&gt;&lt;span class="k"&gt;static&lt;/span&gt; &lt;span class="k"&gt;void&lt;/span&gt; &lt;span class="nf"&gt;Main&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kt"&gt;string&lt;/span&gt;&lt;span class="p"&gt;[]&lt;/span&gt; &lt;span class="n"&gt;args&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;BenchmarkSwitcher&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;FromAssembly&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;typeof&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;Program&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="n"&gt;Assembly&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="nf"&gt;Run&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;args&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This way, BenchmarkDotnet will identify all the benchmarks your assembly contains and let you choose which ones to run.&lt;/p&gt;

&lt;h1&gt;
  
  
  Benchmark results
&lt;/h1&gt;

&lt;p&gt;I’ll be running slightly modified, in terms of targets, version of the same benchmark provided by the docs.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight csharp"&gt;&lt;code&gt;    &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nf"&gt;SimpleJob&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;runtimeMoniker&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;RuntimeMoniker&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Net70&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;baseline&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="k"&gt;true&lt;/span&gt;&lt;span class="p"&gt;)]&lt;/span&gt;
    &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nf"&gt;SimpleJob&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;runtimeMoniker&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;RuntimeMoniker&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Net80&lt;/span&gt;&lt;span class="p"&gt;)]&lt;/span&gt;
    &lt;span class="k"&gt;public&lt;/span&gt; &lt;span class="k"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;Benchmarks&lt;/span&gt;
    &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="k"&gt;private&lt;/span&gt; &lt;span class="n"&gt;SHA256&lt;/span&gt; &lt;span class="n"&gt;sha256&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="n"&gt;SHA256&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;Create&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
        &lt;span class="k"&gt;private&lt;/span&gt; &lt;span class="n"&gt;MD5&lt;/span&gt; &lt;span class="n"&gt;md5&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="n"&gt;MD5&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;Create&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
        &lt;span class="k"&gt;private&lt;/span&gt; &lt;span class="kt"&gt;byte&lt;/span&gt;&lt;span class="p"&gt;[]&lt;/span&gt; &lt;span class="n"&gt;data&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

        &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nf"&gt;Params&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="m"&gt;1000&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="m"&gt;10000&lt;/span&gt;&lt;span class="p"&gt;)]&lt;/span&gt;
        &lt;span class="k"&gt;public&lt;/span&gt; &lt;span class="kt"&gt;int&lt;/span&gt; &lt;span class="n"&gt;N&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

        &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;GlobalSetup&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;
        &lt;span class="k"&gt;public&lt;/span&gt; &lt;span class="k"&gt;void&lt;/span&gt; &lt;span class="nf"&gt;Setup&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
        &lt;span class="p"&gt;{&lt;/span&gt;
            &lt;span class="n"&gt;data&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="kt"&gt;byte&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;N&lt;/span&gt;&lt;span class="p"&gt;];&lt;/span&gt;
            &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nf"&gt;Random&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="m"&gt;42&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="nf"&gt;NextBytes&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;data&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
        &lt;span class="p"&gt;}&lt;/span&gt;

        &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;Benchmark&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;
        &lt;span class="k"&gt;public&lt;/span&gt; &lt;span class="kt"&gt;byte&lt;/span&gt;&lt;span class="p"&gt;[]&lt;/span&gt; &lt;span class="nf"&gt;Sha256&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;sha256&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;ComputeHash&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;data&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

        &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;Benchmark&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;
        &lt;span class="k"&gt;public&lt;/span&gt; &lt;span class="kt"&gt;byte&lt;/span&gt;&lt;span class="p"&gt;[]&lt;/span&gt; &lt;span class="nf"&gt;Md5&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;md5&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;ComputeHash&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;data&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;If you were to run it, after it’s done, you’d see something similar to this&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight csharp"&gt;&lt;code&gt;&lt;span class="p"&gt;|&lt;/span&gt; &lt;span class="n"&gt;Method&lt;/span&gt; &lt;span class="p"&gt;|&lt;/span&gt; &lt;span class="n"&gt;Job&lt;/span&gt;      &lt;span class="p"&gt;|&lt;/span&gt; &lt;span class="n"&gt;Runtime&lt;/span&gt;  &lt;span class="p"&gt;|&lt;/span&gt; &lt;span class="n"&gt;N&lt;/span&gt;     &lt;span class="p"&gt;|&lt;/span&gt; &lt;span class="n"&gt;Mean&lt;/span&gt;      &lt;span class="p"&gt;|&lt;/span&gt; &lt;span class="n"&gt;Error&lt;/span&gt;     &lt;span class="p"&gt;|&lt;/span&gt; &lt;span class="n"&gt;StdDev&lt;/span&gt;    &lt;span class="p"&gt;|&lt;/span&gt; &lt;span class="n"&gt;Ratio&lt;/span&gt; &lt;span class="p"&gt;|&lt;/span&gt; &lt;span class="n"&gt;RatioSD&lt;/span&gt; &lt;span class="p"&gt;|&lt;/span&gt;
&lt;span class="p"&gt;|-------&lt;/span&gt; &lt;span class="p"&gt;|---------&lt;/span&gt; &lt;span class="p"&gt;|---------&lt;/span&gt; &lt;span class="p"&gt;|------&lt;/span&gt; &lt;span class="p"&gt;|----------:|----------:|----------:|------:|--------:|&lt;/span&gt;
&lt;span class="p"&gt;|&lt;/span&gt; &lt;span class="n"&gt;Sha256&lt;/span&gt; &lt;span class="p"&gt;|&lt;/span&gt; &lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;NET&lt;/span&gt; &lt;span class="m"&gt;7.0&lt;/span&gt; &lt;span class="p"&gt;|&lt;/span&gt; &lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;NET&lt;/span&gt; &lt;span class="m"&gt;7.0&lt;/span&gt; &lt;span class="p"&gt;|&lt;/span&gt; &lt;span class="m"&gt;1000&lt;/span&gt;  &lt;span class="p"&gt;|&lt;/span&gt;        &lt;span class="n"&gt;NA&lt;/span&gt; &lt;span class="p"&gt;|&lt;/span&gt;        &lt;span class="n"&gt;NA&lt;/span&gt; &lt;span class="p"&gt;|&lt;/span&gt;        &lt;span class="n"&gt;NA&lt;/span&gt; &lt;span class="p"&gt;|&lt;/span&gt;     &lt;span class="p"&gt;?&lt;/span&gt; &lt;span class="p"&gt;|&lt;/span&gt;       &lt;span class="p"&gt;?&lt;/span&gt; &lt;span class="p"&gt;|&lt;/span&gt;
&lt;span class="p"&gt;|&lt;/span&gt; &lt;span class="n"&gt;Sha256&lt;/span&gt; &lt;span class="p"&gt;|&lt;/span&gt; &lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;NET&lt;/span&gt; &lt;span class="m"&gt;8.0&lt;/span&gt; &lt;span class="p"&gt;|&lt;/span&gt; &lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;NET&lt;/span&gt; &lt;span class="m"&gt;8.0&lt;/span&gt; &lt;span class="p"&gt;|&lt;/span&gt; &lt;span class="m"&gt;1000&lt;/span&gt;  &lt;span class="p"&gt;|&lt;/span&gt;  &lt;span class="m"&gt;1.060&lt;/span&gt; &lt;span class="n"&gt;us&lt;/span&gt; &lt;span class="p"&gt;|&lt;/span&gt; &lt;span class="m"&gt;0.0098&lt;/span&gt; &lt;span class="n"&gt;us&lt;/span&gt; &lt;span class="p"&gt;|&lt;/span&gt; &lt;span class="m"&gt;0.0091&lt;/span&gt; &lt;span class="n"&gt;us&lt;/span&gt; &lt;span class="p"&gt;|&lt;/span&gt;     &lt;span class="p"&gt;?&lt;/span&gt; &lt;span class="p"&gt;|&lt;/span&gt;       &lt;span class="p"&gt;?&lt;/span&gt; &lt;span class="p"&gt;|&lt;/span&gt;
&lt;span class="p"&gt;|&lt;/span&gt;        &lt;span class="p"&gt;|&lt;/span&gt;          &lt;span class="p"&gt;|&lt;/span&gt;          &lt;span class="p"&gt;|&lt;/span&gt;       &lt;span class="p"&gt;|&lt;/span&gt;           &lt;span class="p"&gt;|&lt;/span&gt;           &lt;span class="p"&gt;|&lt;/span&gt;           &lt;span class="p"&gt;|&lt;/span&gt;       &lt;span class="p"&gt;|&lt;/span&gt;         &lt;span class="p"&gt;|&lt;/span&gt;
&lt;span class="p"&gt;|&lt;/span&gt; &lt;span class="n"&gt;Md5&lt;/span&gt;    &lt;span class="p"&gt;|&lt;/span&gt; &lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;NET&lt;/span&gt; &lt;span class="m"&gt;7.0&lt;/span&gt; &lt;span class="p"&gt;|&lt;/span&gt; &lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;NET&lt;/span&gt; &lt;span class="m"&gt;7.0&lt;/span&gt; &lt;span class="p"&gt;|&lt;/span&gt; &lt;span class="m"&gt;1000&lt;/span&gt;  &lt;span class="p"&gt;|&lt;/span&gt;        &lt;span class="n"&gt;NA&lt;/span&gt; &lt;span class="p"&gt;|&lt;/span&gt;        &lt;span class="n"&gt;NA&lt;/span&gt; &lt;span class="p"&gt;|&lt;/span&gt;        &lt;span class="n"&gt;NA&lt;/span&gt; &lt;span class="p"&gt;|&lt;/span&gt;     &lt;span class="p"&gt;?&lt;/span&gt; &lt;span class="p"&gt;|&lt;/span&gt;       &lt;span class="p"&gt;?&lt;/span&gt; &lt;span class="p"&gt;|&lt;/span&gt;
&lt;span class="p"&gt;|&lt;/span&gt; &lt;span class="n"&gt;Md5&lt;/span&gt;    &lt;span class="p"&gt;|&lt;/span&gt; &lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;NET&lt;/span&gt; &lt;span class="m"&gt;8.0&lt;/span&gt; &lt;span class="p"&gt;|&lt;/span&gt; &lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;NET&lt;/span&gt; &lt;span class="m"&gt;8.0&lt;/span&gt; &lt;span class="p"&gt;|&lt;/span&gt; &lt;span class="m"&gt;1000&lt;/span&gt;  &lt;span class="p"&gt;|&lt;/span&gt;  &lt;span class="m"&gt;1.486&lt;/span&gt; &lt;span class="n"&gt;us&lt;/span&gt; &lt;span class="p"&gt;|&lt;/span&gt; &lt;span class="m"&gt;0.0084&lt;/span&gt; &lt;span class="n"&gt;us&lt;/span&gt; &lt;span class="p"&gt;|&lt;/span&gt; &lt;span class="m"&gt;0.0078&lt;/span&gt; &lt;span class="n"&gt;us&lt;/span&gt; &lt;span class="p"&gt;|&lt;/span&gt;     &lt;span class="p"&gt;?&lt;/span&gt; &lt;span class="p"&gt;|&lt;/span&gt;       &lt;span class="p"&gt;?&lt;/span&gt; &lt;span class="p"&gt;|&lt;/span&gt;
&lt;span class="p"&gt;|&lt;/span&gt;        &lt;span class="p"&gt;|&lt;/span&gt;          &lt;span class="p"&gt;|&lt;/span&gt;          &lt;span class="p"&gt;|&lt;/span&gt;       &lt;span class="p"&gt;|&lt;/span&gt;           &lt;span class="p"&gt;|&lt;/span&gt;           &lt;span class="p"&gt;|&lt;/span&gt;           &lt;span class="p"&gt;|&lt;/span&gt;       &lt;span class="p"&gt;|&lt;/span&gt;         &lt;span class="p"&gt;|&lt;/span&gt;
&lt;span class="p"&gt;|&lt;/span&gt; &lt;span class="n"&gt;Sha256&lt;/span&gt; &lt;span class="p"&gt;|&lt;/span&gt; &lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;NET&lt;/span&gt; &lt;span class="m"&gt;7.0&lt;/span&gt; &lt;span class="p"&gt;|&lt;/span&gt; &lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;NET&lt;/span&gt; &lt;span class="m"&gt;7.0&lt;/span&gt; &lt;span class="p"&gt;|&lt;/span&gt; &lt;span class="m"&gt;10000&lt;/span&gt; &lt;span class="p"&gt;|&lt;/span&gt;        &lt;span class="n"&gt;NA&lt;/span&gt; &lt;span class="p"&gt;|&lt;/span&gt;        &lt;span class="n"&gt;NA&lt;/span&gt; &lt;span class="p"&gt;|&lt;/span&gt;        &lt;span class="n"&gt;NA&lt;/span&gt; &lt;span class="p"&gt;|&lt;/span&gt;     &lt;span class="p"&gt;?&lt;/span&gt; &lt;span class="p"&gt;|&lt;/span&gt;       &lt;span class="p"&gt;?&lt;/span&gt; &lt;span class="p"&gt;|&lt;/span&gt;
&lt;span class="p"&gt;|&lt;/span&gt; &lt;span class="n"&gt;Sha256&lt;/span&gt; &lt;span class="p"&gt;|&lt;/span&gt; &lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;NET&lt;/span&gt; &lt;span class="m"&gt;8.0&lt;/span&gt; &lt;span class="p"&gt;|&lt;/span&gt; &lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;NET&lt;/span&gt; &lt;span class="m"&gt;8.0&lt;/span&gt; &lt;span class="p"&gt;|&lt;/span&gt; &lt;span class="m"&gt;10000&lt;/span&gt; &lt;span class="p"&gt;|&lt;/span&gt;  &lt;span class="m"&gt;6.392&lt;/span&gt; &lt;span class="n"&gt;us&lt;/span&gt; &lt;span class="p"&gt;|&lt;/span&gt; &lt;span class="m"&gt;0.0537&lt;/span&gt; &lt;span class="n"&gt;us&lt;/span&gt; &lt;span class="p"&gt;|&lt;/span&gt; &lt;span class="m"&gt;0.0476&lt;/span&gt; &lt;span class="n"&gt;us&lt;/span&gt; &lt;span class="p"&gt;|&lt;/span&gt;     &lt;span class="p"&gt;?&lt;/span&gt; &lt;span class="p"&gt;|&lt;/span&gt;       &lt;span class="p"&gt;?&lt;/span&gt; &lt;span class="p"&gt;|&lt;/span&gt;
&lt;span class="p"&gt;|&lt;/span&gt;        &lt;span class="p"&gt;|&lt;/span&gt;          &lt;span class="p"&gt;|&lt;/span&gt;          &lt;span class="p"&gt;|&lt;/span&gt;       &lt;span class="p"&gt;|&lt;/span&gt;           &lt;span class="p"&gt;|&lt;/span&gt;           &lt;span class="p"&gt;|&lt;/span&gt;           &lt;span class="p"&gt;|&lt;/span&gt;       &lt;span class="p"&gt;|&lt;/span&gt;         &lt;span class="p"&gt;|&lt;/span&gt;
&lt;span class="p"&gt;|&lt;/span&gt; &lt;span class="n"&gt;Md5&lt;/span&gt;    &lt;span class="p"&gt;|&lt;/span&gt; &lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;NET&lt;/span&gt; &lt;span class="m"&gt;7.0&lt;/span&gt; &lt;span class="p"&gt;|&lt;/span&gt; &lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;NET&lt;/span&gt; &lt;span class="m"&gt;7.0&lt;/span&gt; &lt;span class="p"&gt;|&lt;/span&gt; &lt;span class="m"&gt;10000&lt;/span&gt; &lt;span class="p"&gt;|&lt;/span&gt;        &lt;span class="n"&gt;NA&lt;/span&gt; &lt;span class="p"&gt;|&lt;/span&gt;        &lt;span class="n"&gt;NA&lt;/span&gt; &lt;span class="p"&gt;|&lt;/span&gt;        &lt;span class="n"&gt;NA&lt;/span&gt; &lt;span class="p"&gt;|&lt;/span&gt;     &lt;span class="p"&gt;?&lt;/span&gt; &lt;span class="p"&gt;|&lt;/span&gt;       &lt;span class="p"&gt;?&lt;/span&gt; &lt;span class="p"&gt;|&lt;/span&gt;
&lt;span class="p"&gt;|&lt;/span&gt; &lt;span class="n"&gt;Md5&lt;/span&gt;    &lt;span class="p"&gt;|&lt;/span&gt; &lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;NET&lt;/span&gt; &lt;span class="m"&gt;8.0&lt;/span&gt; &lt;span class="p"&gt;|&lt;/span&gt; &lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;NET&lt;/span&gt; &lt;span class="m"&gt;8.0&lt;/span&gt; &lt;span class="p"&gt;|&lt;/span&gt; &lt;span class="m"&gt;10000&lt;/span&gt; &lt;span class="p"&gt;|&lt;/span&gt; &lt;span class="m"&gt;11.898&lt;/span&gt; &lt;span class="n"&gt;us&lt;/span&gt; &lt;span class="p"&gt;|&lt;/span&gt; &lt;span class="m"&gt;0.0236&lt;/span&gt; &lt;span class="n"&gt;us&lt;/span&gt; &lt;span class="p"&gt;|&lt;/span&gt; &lt;span class="m"&gt;0.0209&lt;/span&gt; &lt;span class="n"&gt;us&lt;/span&gt; &lt;span class="p"&gt;|&lt;/span&gt;     &lt;span class="p"&gt;?&lt;/span&gt; &lt;span class="p"&gt;|&lt;/span&gt;       &lt;span class="p"&gt;?&lt;/span&gt; &lt;span class="p"&gt;|&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This table basically shows us comparison of these two algorithms for each version and for two different parameters in terms of &lt;code&gt;N&lt;/code&gt;. BenchmarkDotnet makes sure you understand everything you see on this table, so after every benchmark you’ll be provided with legends grid, explaining what all of these means.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight csharp"&gt;&lt;code&gt;&lt;span class="c1"&gt;// * Legends *&lt;/span&gt;
  &lt;span class="n"&gt;N&lt;/span&gt;       &lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;Value&lt;/span&gt; &lt;span class="n"&gt;of&lt;/span&gt; &lt;span class="n"&gt;the&lt;/span&gt; &lt;span class="sc"&gt;'N'&lt;/span&gt; &lt;span class="n"&gt;parameter&lt;/span&gt;
  &lt;span class="n"&gt;Mean&lt;/span&gt;    &lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;Arithmetic&lt;/span&gt; &lt;span class="n"&gt;mean&lt;/span&gt; &lt;span class="n"&gt;of&lt;/span&gt; &lt;span class="n"&gt;all&lt;/span&gt; &lt;span class="n"&gt;measurements&lt;/span&gt;
  &lt;span class="n"&gt;Error&lt;/span&gt;   &lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;Half&lt;/span&gt; &lt;span class="n"&gt;of&lt;/span&gt; &lt;span class="m"&gt;99.9&lt;/span&gt;&lt;span class="p"&gt;%&lt;/span&gt; &lt;span class="n"&gt;confidence&lt;/span&gt; &lt;span class="n"&gt;interval&lt;/span&gt;
  &lt;span class="n"&gt;StdDev&lt;/span&gt;  &lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;Standard&lt;/span&gt; &lt;span class="n"&gt;deviation&lt;/span&gt; &lt;span class="n"&gt;of&lt;/span&gt; &lt;span class="n"&gt;all&lt;/span&gt; &lt;span class="n"&gt;measurements&lt;/span&gt;
  &lt;span class="n"&gt;Ratio&lt;/span&gt;   &lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;Mean&lt;/span&gt; &lt;span class="n"&gt;of&lt;/span&gt; &lt;span class="n"&gt;the&lt;/span&gt; &lt;span class="n"&gt;ratio&lt;/span&gt; &lt;span class="nf"&gt;distribution&lt;/span&gt; &lt;span class="p"&gt;([&lt;/span&gt;&lt;span class="n"&gt;Current&lt;/span&gt;&lt;span class="p"&gt;]/[&lt;/span&gt;&lt;span class="n"&gt;Baseline&lt;/span&gt;&lt;span class="p"&gt;])&lt;/span&gt;
  &lt;span class="n"&gt;RatioSD&lt;/span&gt; &lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;Standard&lt;/span&gt; &lt;span class="n"&gt;deviation&lt;/span&gt; &lt;span class="n"&gt;of&lt;/span&gt; &lt;span class="n"&gt;the&lt;/span&gt; &lt;span class="n"&gt;ratio&lt;/span&gt; &lt;span class="nf"&gt;distribution&lt;/span&gt; &lt;span class="p"&gt;([&lt;/span&gt;&lt;span class="n"&gt;Current&lt;/span&gt;&lt;span class="p"&gt;]/[&lt;/span&gt;&lt;span class="n"&gt;Baseline&lt;/span&gt;&lt;span class="p"&gt;])&lt;/span&gt;
  &lt;span class="m"&gt;1&lt;/span&gt; &lt;span class="n"&gt;us&lt;/span&gt;    &lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="m"&gt;1&lt;/span&gt; &lt;span class="nf"&gt;Microsecond&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="m"&gt;0.000001&lt;/span&gt; &lt;span class="n"&gt;sec&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h1&gt;
  
  
  Conclusion
&lt;/h1&gt;

&lt;p&gt;While BenchmarkDotnet will not supercharge your code to run faster or make you a 10x engineer, it’s nice to have in your toolbox. I remember making monstrosities out of stopwatches and &lt;code&gt;Console.WriteLine&lt;/code&gt; just to compare the runtime speed of several methods, we’ve all been there and I’m pretty sure you can’t reach the same level of accuracy with those. &lt;/p&gt;

&lt;p&gt;Thank you for taking the time to read! :)&lt;br&gt;
All of the stories are also available at my personal website - &lt;a href="https://anakidze.dev"&gt;https://anakidze.dev&lt;/a&gt;&lt;/p&gt;

</description>
      <category>programming</category>
      <category>dotnet</category>
      <category>beginners</category>
      <category>webdev</category>
    </item>
    <item>
      <title>Zero-Cost Database Magic 🪄💾</title>
      <dc:creator>Giorgi Anakidze</dc:creator>
      <pubDate>Fri, 29 Sep 2023 21:28:47 +0000</pubDate>
      <link>https://dev.to/gpskwlkr/zero-cost-database-magic-19d5</link>
      <guid>https://dev.to/gpskwlkr/zero-cost-database-magic-19d5</guid>
      <description>&lt;p&gt;&lt;a href="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fuklri4m51qkfvww7whbh.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fuklri4m51qkfvww7whbh.png" alt="Generic Database Image" width="800" height="446"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Whether you’re a hobbyist or a professional developer, at some point you’re going to need a database. 😄 We all know the famous solutions like AWS, Azure, or maybe something that’s more affordable like Linode or DigitalOcean, but what if you only need a database to test some of your ideas? 🤔 Spinning up your own instance with Docker or just installing it locally may not always be an option. 😅 I wish there were some database services that would be performant enough for testing your ideas and also were free… Well, guess what? There are! 😎 And in this article, I’m going to show off 5 of them, so you can choose the best one for your project! 🚀&lt;/p&gt;

&lt;h2&gt;
  
  
  PlanetScale 🌍
&lt;/h2&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F5cbdus8w2uy9lfqkb6wb.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F5cbdus8w2uy9lfqkb6wb.png" alt="PlanetScale logo" width="800" height="534"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;PlanetScale&lt;/strong&gt; is a serverless platform for MySQL which offers really good options on a free tier. 🤩 I think it’d suit most of the developers who want to use MySQL and to save up some money as well. 💵 Here’s a short brief of what the free tier has to offer:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Storage - 5GB&lt;/strong&gt; 📦&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Reads per month - 1 Billion&lt;/strong&gt; 📖&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Writes per month - 10 Million&lt;/strong&gt; ✍️&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;1 Production Branch&lt;/strong&gt; 🌳&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;1 Development Branch&lt;/strong&gt; 🌱&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;As you see, &lt;a href="https://planetscale.com/"&gt;&lt;strong&gt;PlanetScale&lt;/strong&gt;&lt;/a&gt; has a pretty good free tier, but there’s one more service that has even more in theirs, so make sure to read to the end! 😉&lt;/p&gt;

&lt;h2&gt;
  
  
  Cloudflare D1 🌐
&lt;/h2&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F13jhfi4g8chnqjjjazw1.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F13jhfi4g8chnqjjjazw1.png" alt="Cloudflare D1 Logo" width="720" height="405"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Cloudflare D1&lt;/strong&gt; is basically a SQLite database that runs on the edge and is used with Cloudflare Workers. So, if you have your web service deployed to Workers which is also running on the edge, it means that your users will be able to always connect to the closest server and get the least amount of latency for them. ⚡ Here’s a short brief of what the free tier has to offer:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Serverless SQL Database&lt;/strong&gt; 🗄️&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Reads per day - 5 Million&lt;/strong&gt; 📖&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Writes per day - 100K&lt;/strong&gt; ✍️&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;If you’re someone who enjoys using &lt;strong&gt;Cloudflare Workers&lt;/strong&gt;, D1 might be the best choice for you, make sure to check it out at - &lt;strong&gt;&lt;a href="https://developers.cloudflare.com/d1/"&gt;Cloudflare D1&lt;/a&gt;&lt;/strong&gt;. 🎉&lt;/p&gt;

&lt;h2&gt;
  
  
  Xata 📊
&lt;/h2&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fztevy6ds45r957qnuk2a.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fztevy6ds45r957qnuk2a.png" alt="Xata Logo" width="800" height="450"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Xata&lt;/strong&gt; is another serverless relational database that is based on PostgreSQL and ElasticSearch under the hood. 🚀 It treats your tables like a spreadsheet and what’s really cool about it is that it has full-text search built-in. 🔍 No need to duplicate data to an ElasticSearch instance! They have SDKs for many languages and a visual schema editor. Here’s a short brief of what the free tier has to offer:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;15 GB Storage for your data&lt;/strong&gt; 📦&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Total records - 750K&lt;/strong&gt; 📈&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Branches per database - 15&lt;/strong&gt; 🌳&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Requests per second - 75&lt;/strong&gt; ⚡
Make sure to check it out at - &lt;a href="https://xata.io/"&gt;&lt;strong&gt;Xata&lt;/strong&gt;&lt;/a&gt;. 😃&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Fauna 🐾
&lt;/h2&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fzfrzvy0e5fyw9uyb76kv.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fzfrzvy0e5fyw9uyb76kv.png" alt="Fauna Logo" width="800" height="418"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://fauna.com/"&gt;&lt;strong&gt;Fauna&lt;/strong&gt;&lt;/a&gt; is another serverless database created by ex-Twitter engineers. It's kind of like MongoDB, but with native JOIN operations, many document databases miss. They have their own language, FQL, and also a GraphQL API. Here's a quick overview of their free tier:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;100K TROs (Total Read Operations)&lt;/strong&gt; 📖&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;50K TWOs (Total Write Operations)&lt;/strong&gt; ✍️&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;1GB Storage&lt;/strong&gt; 📦&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;5 Databases&lt;/strong&gt; 🗄️
Sounds good, but the next one is my personal favorite! 🌟&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Neon 💡
&lt;/h2&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fweyc9zoijgncs7lj51rp.jpg" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fweyc9zoijgncs7lj51rp.jpg" alt="Neon Logo" width="800" height="533"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Neon&lt;/strong&gt; is a serverless PostgreSQL option written in Rust. 🎉 It has a great free tier, good docs, and supports data branching for various environments. Here's a glance at their free tier:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Storage - 3GiB&lt;/strong&gt; 📦&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Branches - 10&lt;/strong&gt; 🌳&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Active time per month - 100 hours (Primary branch stays active even if you go over!)&lt;/strong&gt; ⏳&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;History retention - 7 days&lt;/strong&gt; 🗓️&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Choose the PostgreSQL version and server location&lt;/strong&gt; 🌍&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;By far, &lt;strong&gt;Neon&lt;/strong&gt; is my top pick! Check it out for yourself at - &lt;a href="https://neon.tech/"&gt;&lt;strong&gt;Neon&lt;/strong&gt;&lt;/a&gt;. 🚀&lt;/p&gt;

&lt;p&gt;Enjoy these databases and happy coding! 😊&lt;/p&gt;

&lt;p&gt;Thank you for taking the time to read! :)&lt;br&gt;
All of the stories are also available at my personal website - &lt;a href="https://anakidze.dev"&gt;https://anakidze.dev&lt;/a&gt;&lt;/p&gt;

</description>
      <category>webdev</category>
      <category>database</category>
      <category>beginners</category>
      <category>programming</category>
    </item>
    <item>
      <title>Entity Framework: 5 Rookie Traps</title>
      <dc:creator>Giorgi Anakidze</dc:creator>
      <pubDate>Tue, 26 Sep 2023 22:04:24 +0000</pubDate>
      <link>https://dev.to/gpskwlkr/entity-framework-5-rookie-traps-10cl</link>
      <guid>https://dev.to/gpskwlkr/entity-framework-5-rookie-traps-10cl</guid>
      <description>&lt;p&gt;&lt;a href="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fe8cc893728jg2bkbd0ur.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fe8cc893728jg2bkbd0ur.png" alt="EF Core" width="720" height="401"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;I’m pretty sure that everyone who works with C#/.NET has heard at least once about Entity Framework (EF). Whether it’s good or bad, it’s used widely and it will benefit you to know how to work with it. But what happens when a beginner developer enters the .NET world and sees the picture where EF is promoted everywhere? All of the job requirements include it and you can find plenty of guides on it. We can’t ignore that EF gives you a lot of benefits, but some caveats may be not so visible for a beginner developer and in this article, I’d like to introduce them to you.&lt;/p&gt;

&lt;h2&gt;
  
  
  1. Control over the DB while doing Code-First
&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;Scenario:&lt;/strong&gt;&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Imagine having a simple User model for your database.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Like the one below:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight csharp"&gt;&lt;code&gt;&lt;span class="k"&gt;public&lt;/span&gt; &lt;span class="k"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;User&lt;/span&gt;
&lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;public&lt;/span&gt; &lt;span class="kt"&gt;int&lt;/span&gt; &lt;span class="n"&gt;Id&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="k"&gt;get&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="k"&gt;set&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt;
    &lt;span class="k"&gt;public&lt;/span&gt; &lt;span class="kt"&gt;string&lt;/span&gt; &lt;span class="n"&gt;FirstName&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="k"&gt;get&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="k"&gt;set&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt;
    &lt;span class="k"&gt;public&lt;/span&gt; &lt;span class="kt"&gt;string&lt;/span&gt; &lt;span class="n"&gt;LastName&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="k"&gt;get&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="k"&gt;set&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt;
    &lt;span class="k"&gt;public&lt;/span&gt; &lt;span class="kt"&gt;string&lt;/span&gt; &lt;span class="n"&gt;Email&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="k"&gt;get&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="k"&gt;set&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt;
    &lt;span class="k"&gt;public&lt;/span&gt; &lt;span class="kt"&gt;string&lt;/span&gt; &lt;span class="n"&gt;Password&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="k"&gt;get&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="k"&gt;set&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="c1"&gt;// DbContext declaration&lt;/span&gt;
&lt;span class="c1"&gt;// ...&lt;/span&gt;
&lt;span class="k"&gt;public&lt;/span&gt; &lt;span class="n"&gt;DbSet&lt;/span&gt;&lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;User&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;Users&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="k"&gt;get&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="k"&gt;set&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;And since you’re a beginner you might think it’s completely fine, but this is what you end up having in your database:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fo2hcaj4q7l6dqe4siqtc.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fo2hcaj4q7l6dqe4siqtc.png" alt="Screenshot of a table with nvarchar(max) on all columns" width="205" height="93"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;As you might see, if you don’t specify any length to your string fields, EF will default it to nvarchar(max) and you might be asking, so what? What’s wrong with that? I have plenty of reasons why you should never use it unless it’s really necessary for business needs:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;    nvarchar(max) fields can potentially store up to 2GB of data for each row. So when the data is queried, the database might allocate memory based on the potential size of the column, even if only a fraction of it is used, which leads to inefficient memory usage.&lt;/li&gt;
&lt;li&gt;    You can’t apply any traditional indexes to nvarchar(max) columns. You could still use full-text indexes or indexed views in some cases, but it will still limit your performance optimization options.&lt;/li&gt;
&lt;li&gt;    With all of that said above, data retrieval could be slow because of nvarchar(max) , especially when they are being used for JOIN operations&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;So, including all cons of nvarchar(max) what you should consider is refactoring your DB model to be like:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight csharp"&gt;&lt;code&gt;&lt;span class="k"&gt;public&lt;/span&gt; &lt;span class="k"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;User&lt;/span&gt;
&lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;public&lt;/span&gt; &lt;span class="kt"&gt;int&lt;/span&gt; &lt;span class="n"&gt;Id&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="k"&gt;get&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="k"&gt;set&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt;
    &lt;span class="c1"&gt;// if you want FirstName to remain nvarchar type&lt;/span&gt;
    &lt;span class="c1"&gt;// but limit it's length&lt;/span&gt;
    &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nf"&gt;MaxLength&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="m"&gt;200&lt;/span&gt;&lt;span class="p"&gt;)]&lt;/span&gt;
    &lt;span class="k"&gt;public&lt;/span&gt; &lt;span class="kt"&gt;string&lt;/span&gt; &lt;span class="n"&gt;FirstName&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="k"&gt;get&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="k"&gt;set&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt;
    &lt;span class="c1"&gt;// or even better&lt;/span&gt;
    &lt;span class="c1"&gt;// if you only allow alphanumeric characters&lt;/span&gt;
    &lt;span class="c1"&gt;// or special characters &amp;amp; whitespace&lt;/span&gt;
    &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nf"&gt;Column&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;TypeName&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="s"&gt;"varchar(200)"&lt;/span&gt;&lt;span class="p"&gt;)]&lt;/span&gt;
    &lt;span class="k"&gt;public&lt;/span&gt; &lt;span class="kt"&gt;string&lt;/span&gt; &lt;span class="n"&gt;LastName&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="k"&gt;get&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="k"&gt;set&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt;
    &lt;span class="k"&gt;public&lt;/span&gt; &lt;span class="kt"&gt;string&lt;/span&gt; &lt;span class="n"&gt;Email&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="k"&gt;get&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="k"&gt;set&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt;
    &lt;span class="k"&gt;public&lt;/span&gt; &lt;span class="kt"&gt;string&lt;/span&gt; &lt;span class="n"&gt;Password&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="k"&gt;get&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="k"&gt;set&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Always check your model for having your string fields limited by length or column data type.&lt;/p&gt;

&lt;h2&gt;
  
  
  2. Lazy Loading vs. Eager Loading
&lt;/h2&gt;

&lt;p&gt;Many beginners might have spotted some performance problems with their EF queries. Entity Framework is not forcing you to use Lazy Loading or Eager Loading, you get to choose what to do. But first, before we talk about what are the pros and cons of each of them, let’s dive into how they work.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Lazy Loading&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Lazy Loading is a feature that allows EF to query the data on an as-needed basis.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Scenario:&lt;/strong&gt;&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Imagine having a blog where users should be allowed to have many posts.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;So you build some simple models like this:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight csharp"&gt;&lt;code&gt;&lt;span class="k"&gt;public&lt;/span&gt; &lt;span class="k"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;User&lt;/span&gt;
&lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;public&lt;/span&gt; &lt;span class="kt"&gt;int&lt;/span&gt; &lt;span class="n"&gt;Id&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="k"&gt;get&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="k"&gt;set&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt;
    &lt;span class="k"&gt;public&lt;/span&gt; &lt;span class="kt"&gt;string&lt;/span&gt; &lt;span class="n"&gt;FirstName&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="k"&gt;get&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="k"&gt;set&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt;
    &lt;span class="k"&gt;public&lt;/span&gt; &lt;span class="kt"&gt;string&lt;/span&gt; &lt;span class="n"&gt;LastName&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="k"&gt;get&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="k"&gt;set&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt;
    &lt;span class="k"&gt;public&lt;/span&gt; &lt;span class="kt"&gt;string&lt;/span&gt; &lt;span class="n"&gt;Email&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="k"&gt;get&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="k"&gt;set&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt;
    &lt;span class="k"&gt;public&lt;/span&gt; &lt;span class="kt"&gt;string&lt;/span&gt; &lt;span class="n"&gt;Password&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="k"&gt;get&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="k"&gt;set&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt;

    &lt;span class="k"&gt;public&lt;/span&gt; &lt;span class="n"&gt;ICollection&lt;/span&gt;&lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;Post&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;Posts&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="k"&gt;get&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="k"&gt;set&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="k"&gt;public&lt;/span&gt; &lt;span class="k"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;Post&lt;/span&gt;
&lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;public&lt;/span&gt; &lt;span class="kt"&gt;int&lt;/span&gt; &lt;span class="n"&gt;PostId&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="k"&gt;get&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="k"&gt;set&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt;
    &lt;span class="k"&gt;public&lt;/span&gt; &lt;span class="kt"&gt;string&lt;/span&gt; &lt;span class="n"&gt;Title&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="k"&gt;get&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="k"&gt;set&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt;
    &lt;span class="k"&gt;public&lt;/span&gt; &lt;span class="kt"&gt;string&lt;/span&gt; &lt;span class="n"&gt;Content&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="k"&gt;get&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="k"&gt;set&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;And later on in your service, you query the user with all the posts&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight csharp"&gt;&lt;code&gt;&lt;span class="c1"&gt;// method declaration&lt;/span&gt;
&lt;span class="c1"&gt;// ...&lt;/span&gt;
&lt;span class="kt"&gt;var&lt;/span&gt; &lt;span class="n"&gt;users&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="n"&gt;_dbContext&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Users&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;ToList&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
&lt;span class="k"&gt;foreach&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kt"&gt;var&lt;/span&gt; &lt;span class="n"&gt;user&lt;/span&gt; &lt;span class="k"&gt;in&lt;/span&gt; &lt;span class="n"&gt;users&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;foreach&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kt"&gt;var&lt;/span&gt; &lt;span class="n"&gt;post&lt;/span&gt; &lt;span class="k"&gt;in&lt;/span&gt; &lt;span class="n"&gt;user&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Posts&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="p"&gt;{&lt;/span&gt;
      &lt;span class="n"&gt;Console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;WriteLine&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;post&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Title&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;You might be thinking that it’s cool to load data only when you need it, so you’re not overloading your database, but what happens is that if you have 1 user who has 100 posts on your blog, you’re making 101 separate queries, 1 to query the user and 100 others to query all the posts.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Often referred to as N+1 problem.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;That’s when Eager Loading comes in to save your database!&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Eager Loading&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;On the other side, Eager Loading is a feature that allows EF to query all the required data in a single query and map it as your model declares. In terms of code, you’ve got the new .Include() method.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight csharp"&gt;&lt;code&gt;&lt;span class="kt"&gt;var&lt;/span&gt; &lt;span class="n"&gt;users&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="n"&gt;_dbContext&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Users&lt;/span&gt;
                      &lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;Include&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;u&lt;/span&gt; &lt;span class="p"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;u&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Posts&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
                      &lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;ToList&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;And that’s it. Now you’ve queried all the users with all of their posts in a single query which is a more efficient approach while working with big data models as blog posts.&lt;/p&gt;

&lt;h2&gt;
  
  
  3. Ignoring Database Migrations
&lt;/h2&gt;

&lt;p&gt;EF provides a mechanism called “Migrations” to help you manage changes to the database schema. You add a new migration each time you’ve changed a database entity model and EF generates a set of commands it then executes to update the database table according to your model. Beginners often forget to apply their migrations to the database which can lead to having certain errors later on. If you’re someone who loves working from CLI, execute these commands after each change to keep your database in sync with your entities.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;dotnet ef migrations add nameOfMigration
dotnet ef database update
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;blockquote&gt;
&lt;p&gt;Make sure you’ve installed &lt;a href="https://learn.microsoft.com/en-us/ef/core/cli/dotnet"&gt;EF Tools&lt;/a&gt; before executing these commands.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;h2&gt;
  
  
  4. Not keeping track of SQL generated by EF
&lt;/h2&gt;

&lt;p&gt;EF abstracts the SQL generation process, which can be a double-edged sword. While it allows developers to work without worrying about SQL, it can lead to inefficient or unexpected SQL code generated.&lt;/p&gt;

&lt;p&gt;Let’s have kinda same example and see how EF generates SQL code and how can we do it ourselves.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Scenario:&lt;/strong&gt;&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Imagine you have a Users table and a Purchases table. You want to fetch all users who have made more than 5 purchases.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Using EF you might write something like this:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight csharp"&gt;&lt;code&gt;&lt;span class="kt"&gt;var&lt;/span&gt; &lt;span class="n"&gt;usersWithMoreThanFivePurchases&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="n"&gt;context&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Users&lt;/span&gt;
    &lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;Where&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;u&lt;/span&gt; &lt;span class="p"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;u&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Purchases&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;Count&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;&amp;gt;&lt;/span&gt; &lt;span class="m"&gt;5&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;ToList&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Which might later be translated to SQL like this:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight sql"&gt;&lt;code&gt;&lt;span class="k"&gt;SELECT&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;u&lt;/span&gt;&lt;span class="p"&gt;].[&lt;/span&gt;&lt;span class="n"&gt;UserId&lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;u&lt;/span&gt;&lt;span class="p"&gt;].[&lt;/span&gt;&lt;span class="n"&gt;Username&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;
&lt;span class="k"&gt;FROM&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;Users&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="k"&gt;AS&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;u&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;
&lt;span class="k"&gt;WHERE&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;
    &lt;span class="k"&gt;SELECT&lt;/span&gt; &lt;span class="k"&gt;COUNT&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="k"&gt;FROM&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;Purchases&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="k"&gt;AS&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;p&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;
    &lt;span class="k"&gt;WHERE&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;u&lt;/span&gt;&lt;span class="p"&gt;].[&lt;/span&gt;&lt;span class="n"&gt;UserId&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;p&lt;/span&gt;&lt;span class="p"&gt;].[&lt;/span&gt;&lt;span class="n"&gt;UserId&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;
&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="mi"&gt;5&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This query is truly not the best I’ve seen due to several reasons. So, what are those reasons:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;    Subquery overhead. For each object in the Users table, a subquery is run to check how many purchases were made. If the Users table has a lot of entries, this could be very inefficient.&lt;/li&gt;
&lt;li&gt;    No JOIN operations. In this case, the JOIN operation might be more efficient to use, however, the abstraction might not always choose the most optimal path.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;How would we write the same query, if it was handwritten?&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight sql"&gt;&lt;code&gt;&lt;span class="k"&gt;SELECT&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;u&lt;/span&gt;&lt;span class="p"&gt;].[&lt;/span&gt;&lt;span class="n"&gt;UserId&lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;u&lt;/span&gt;&lt;span class="p"&gt;].[&lt;/span&gt;&lt;span class="n"&gt;Username&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;
&lt;span class="k"&gt;FROM&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;Users&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="k"&gt;AS&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;u&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;
&lt;span class="k"&gt;JOIN&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;Purchases&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="k"&gt;AS&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;p&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="k"&gt;ON&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;u&lt;/span&gt;&lt;span class="p"&gt;].[&lt;/span&gt;&lt;span class="n"&gt;UserId&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;p&lt;/span&gt;&lt;span class="p"&gt;].[&lt;/span&gt;&lt;span class="n"&gt;UserId&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;
&lt;span class="k"&gt;GROUP&lt;/span&gt; &lt;span class="k"&gt;BY&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;u&lt;/span&gt;&lt;span class="p"&gt;].[&lt;/span&gt;&lt;span class="n"&gt;UserId&lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;u&lt;/span&gt;&lt;span class="p"&gt;].[&lt;/span&gt;&lt;span class="n"&gt;Username&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;
&lt;span class="k"&gt;HAVING&lt;/span&gt; &lt;span class="k"&gt;COUNT&lt;/span&gt;&lt;span class="p"&gt;([&lt;/span&gt;&lt;span class="n"&gt;p&lt;/span&gt;&lt;span class="p"&gt;].[&lt;/span&gt;&lt;span class="n"&gt;PurchaseId&lt;/span&gt;&lt;span class="p"&gt;])&lt;/span&gt; &lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="mi"&gt;5&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;In this case, we’re using JOIN operation, then using GROUP BY clause to get rid of the possible duplicates and finally checking the count of purchases with HAVING clause.&lt;/p&gt;

&lt;h2&gt;
  
  
  5. Security concerns with RAW SQL
&lt;/h2&gt;

&lt;p&gt;In case you didn’t know, EF lets you execute raw SQL. There are multiple ways to do so, but the most commonly used ones are Migrations and direct execution from DbContext. Both of the methods accept interpolated strings as parameters and there’s a huge flaw in security.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Migrations&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;While executing raw SQL from Migrations, you’ll need to add an empty migration file, where you apply your SQL code later.&lt;/p&gt;

&lt;p&gt;&lt;code&gt;dotnet ef migrations add createstoredprocedure&lt;/code&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight csharp"&gt;&lt;code&gt;&lt;span class="c1"&gt;// Migration code&lt;/span&gt;
&lt;span class="c1"&gt;// ...&lt;/span&gt;
&lt;span class="n"&gt;migrationBuilder&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;Sql&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;$"YourSqlQuery $&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="n"&gt;parameter&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="s"&gt;"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;In terms of creating stored procedures with raw SQL from EF there’s nothing wrong. The problem appears when you are calling it from EF. You might think, what’s the worst that can happen?&lt;/p&gt;

&lt;p&gt;Well, EF is accepting RAW SQL as an interpolated string, which means your parameters are not being converted to SQLParameter class, because it’s the only way EF supports running RAW SQL.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;DbContext&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;So you might say, if EF has a chance of generating bad SQL code, why don’t I use it to run RAW SQL for complex queries? And you could do it, but really carefully. That’s because of the reason I already stated above, EF is not converting your parameters to SQLParameter class, it directly executes all the SQL you give it. The way you do it through DbContext is as follows:&lt;/p&gt;

&lt;p&gt;&lt;code&gt;_context.Users.FromSqlInterpolated($"SELECT FirstName FROM dbo.Users WHERE Id = {id}");&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;As you see, your parameter is directly passed to the SELECT statement. It is not good, to put it mildly. You always got to be careful with such tools, if you screw anything up, you might as well drop your whole DB.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Conclusion&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F984ypg3s1zp4ogf1i836.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F984ypg3s1zp4ogf1i836.png" alt="Meme with Dapper &amp;amp; EF Core" width="750" height="500"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;There will never be a way that’s always good or bad, and you can’t say any of those about EF as well. You have to decide what’s best for your application and how are you going to use it. If you have a small and simple application you might use Entity Framework and won’t even need RAW SQL execution. If you’re building something more complex, you might want to look at Dapper, which gives you the ability to execute RAW SQL and Stored Procedures while converting all parameters to SQLParameter class, guarding your DB from SQL Injection attacks. I might write some article on Dapper as well later, but for now, that’s all, thanks for reading!&lt;/p&gt;

&lt;p&gt;Thank you for taking the time to read! :)&lt;br&gt;
All of the stories are also available at my personal website - &lt;a href="https://anakidze.dev"&gt;https://anakidze.dev&lt;/a&gt;&lt;/p&gt;

</description>
      <category>webdev</category>
      <category>beginners</category>
      <category>dotnet</category>
      <category>csharp</category>
    </item>
    <item>
      <title>Awaiting .NET 8: A Look Back at the .NET Journey</title>
      <dc:creator>Giorgi Anakidze</dc:creator>
      <pubDate>Thu, 21 Sep 2023 20:46:14 +0000</pubDate>
      <link>https://dev.to/gpskwlkr/awaiting-net-8-a-look-back-at-the-net-journey-pjc</link>
      <guid>https://dev.to/gpskwlkr/awaiting-net-8-a-look-back-at-the-net-journey-pjc</guid>
      <description>&lt;p&gt;&lt;a href="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fkc2gxd9udqutrjk1r91a.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fkc2gxd9udqutrjk1r91a.png" alt=".NET Logo" width="800" height="319"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;While the tech world awaits &lt;strong&gt;.NET 8&lt;/strong&gt;, it’s an opportune moment to take a step back and reflect on the transformative journey of &lt;strong&gt;C# &amp;amp; .NET&lt;/strong&gt;. Their evolution was not just a testament to Microsoft’s vision but also the dynamic and ever-changing demands of developers worldwide. This article offers a whirlwind tour of their metamorphosis, highlighting key milestones, and setting the stage for the exciting innovations &lt;strong&gt;.NET 8&lt;/strong&gt; promises to bring.&lt;/p&gt;

&lt;h2&gt;
  
  
  How it all began
&lt;/h2&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fls7hostrk974vbglq6g1.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fls7hostrk974vbglq6g1.png" alt=".NET Framework 1.0 Logo" width="698" height="448"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  .NET Framework 1.0
&lt;/h2&gt;

&lt;p&gt;Released in 2002, &lt;strong&gt;.NET Framework 1.0&lt;/strong&gt; was Microsoft’s answer to a changing software development landscape, aiming to provide a unified environment for developing web services, desktop applications, and other software. The first release included many of the key features that are still being used today, even if they’ve changed as time went by, these were:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;CLR:&lt;/strong&gt; Common Language Runtime&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;BCL:&lt;/strong&gt; Base Class Library&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;ASP.NET:&lt;/strong&gt; For web-based applications, introducing WebForms which allowed for event-driven web development&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;ADO.NET:&lt;/strong&gt; A set of classes for data access, offering disconnected data architecture and XML integration&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Windows Forms:&lt;/strong&gt; For building rich desktop applications and even with the release of WPF or .NET MAUI they’re still being used&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Support for multiple languages:&lt;/strong&gt; One of the main advantages was its ability to support multiple languages, ensuring interoperability&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;As you can see, even though &lt;strong&gt;.NET&lt;/strong&gt; platform is constantly changing and evolving, the key features were a fundament for what we have today, which is being polished to this day. We’ve talked about the platform and now you might be wondering what did &lt;strong&gt;C# 1.0&lt;/strong&gt; had to offer back then.&lt;/p&gt;

&lt;h2&gt;
  
  
  C# 1.0
&lt;/h2&gt;

&lt;p&gt;Introduced alongside &lt;strong&gt;.NET Framework, C# 1.0&lt;/strong&gt; became one of the primary languages designed for the platform. Anders Hejlsberg, who also worked on &lt;strong&gt;Turbo Pascal&lt;/strong&gt; and &lt;strong&gt;Borland Delphi&lt;/strong&gt;, was a chief architect behind &lt;strong&gt;C#&lt;/strong&gt;. As you may guess, &lt;strong&gt;C# 1.0&lt;/strong&gt; was not so rich in features as today, but in the same way as &lt;strong&gt;.NET Framework 1.0&lt;/strong&gt;, it already had all the key concepts included that we’re still using to this day and they’re nowhere to go.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Object-Oriented:&lt;/strong&gt; Full support for classes and the three pillars of Object-Oriented programming (inheritance, polymorphism, and encapsulation)&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Syntax&lt;/strong&gt;, which was heavily influenced by Java and C++, but with a focus on simplicity and productivity, was also related to the next key feature&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Garbage collection:&lt;/strong&gt; Automatic memory management to avoid common programming pitfalls&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Type-Safety:&lt;/strong&gt; C# is designed to be strongly typed to minimize runtime errors and enhance performance&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Declarative programming:&lt;/strong&gt; Attributes in C# allow developers to add metadata to assemblies, classes, etc., which could be then queried at runtime using reflection&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  What has changed
&lt;/h2&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Frok9pg8z5ygvwmjqsbnp.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Frok9pg8z5ygvwmjqsbnp.png" alt=".NET 5 Consolidation information" width="800" height="426"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Although &lt;strong&gt;.NET Framework&lt;/strong&gt; and &lt;strong&gt;C#&lt;/strong&gt; went a long way and there were a ton of features added year to year, the major change happened in November 2020, when &lt;strong&gt;.NET 5&lt;/strong&gt; was released. You might be asking, what did it change for us, developers? Well, let’s see:&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Consolidation of .NET Core and .NET Framework:&lt;/strong&gt; &lt;strong&gt;.NET 5&lt;/strong&gt; was a successor to &lt;strong&gt;.NET Core 3.1&lt;/strong&gt;, it brought an end to the separate &lt;strong&gt;.NET Core&lt;/strong&gt; branding. It’s not here to continue what &lt;strong&gt;.NET Framework&lt;/strong&gt; is but to represent the path forward for the &lt;strong&gt;.NET&lt;/strong&gt; platform as a whole.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Unified Platform for Different Workloads:&lt;/strong&gt; &lt;strong&gt;.NET 5&lt;/strong&gt; allows developers to target various application types such as web, cloud, mobile, gaming, IoT, and AI using a single .NET platform.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Cross-Platform Support: .NET 5&lt;/strong&gt; maintained and improved upon &lt;strong&gt;.NET Core’s&lt;/strong&gt; commitment to cross-platform development, enabling developers to run their applications on Windows, Linux, and MacOS.&lt;/p&gt;

&lt;p&gt;All of this sounds pretty cool, although &lt;strong&gt;.NET 5&lt;/strong&gt; didn’t bring us any GUI development libraries that were cross-platform, and existing ones like &lt;strong&gt;WinForms&lt;/strong&gt; or &lt;strong&gt;WPF&lt;/strong&gt; remained Windows-only technologies.&lt;/p&gt;

&lt;h2&gt;
  
  
  .NET 6/7
&lt;/h2&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fr18cvco9m05omvs4qi2d.jpg" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fr18cvco9m05omvs4qi2d.jpg" alt=".NET MAUI Logo" width="800" height="443"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;In terms of major changes, there were not so many features offered with &lt;strong&gt;.NET 6/7&lt;/strong&gt; releases as in previous versions, but they both provided significant performance improvements and also, we finally have a technology for making GUI applications cross-platform, although, still not possible for Linux. What I’m talking about is — &lt;strong&gt;.NET MAUI&lt;/strong&gt;, which is pretty good, but comes with some caveats.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Yes, you have a cross-platform GUI technology, but Linux is still missing out.&lt;/li&gt;
&lt;li&gt;Yes, you have the ability for AOT compilation to run basically on bare metal, without &lt;strong&gt;.NET Runtime&lt;/strong&gt; installed at all, but not for cross-platform apps, this is still a Windows-only feature.&lt;/li&gt;
&lt;li&gt;And the last one, &lt;strong&gt;.NET MAUI&lt;/strong&gt; is actually pretty good, but you have to write its styling and markup using &lt;strong&gt;HTML &amp;amp; CSS&lt;/strong&gt;, which might be a plus for someone, although old C# developers might be more used to &lt;strong&gt;WinForms&lt;/strong&gt; style or &lt;strong&gt;XAML&lt;/strong&gt;.&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  What to Expect?
&lt;/h2&gt;

&lt;p&gt;Even though &lt;strong&gt;.NET 8&lt;/strong&gt; is set to release in &lt;strong&gt;November 2023&lt;/strong&gt;, we already can try it out! Yes, the &lt;strong&gt;RC1&lt;/strong&gt; is already available and it has a lot to offer, including things like &lt;strong&gt;Native AOT&lt;/strong&gt; for Web applications, &lt;strong&gt;Blazor&lt;/strong&gt; improvements, and &lt;strong&gt;Entity Framework&lt;/strong&gt; updates, make sure to check out all the &lt;a href="https://devblogs.microsoft.com/dotnet/performance-improvements-in-net-8/"&gt;benchmarks&lt;/a&gt; (really big performance improvements) and &lt;a href="https://devblogs.microsoft.com/dotnet/announcing-dotnet-8-rc1/"&gt;RC1&lt;/a&gt; notes. From the revolutionary advancements in Web application development to performance leaps, &lt;strong&gt;.NET 8&lt;/strong&gt; promises a transformative experience for developers. So why wait? Dive into the &lt;strong&gt;RC1&lt;/strong&gt; today and be among the first to feel the power of the future of &lt;strong&gt;.NET&lt;/strong&gt;!&lt;/p&gt;

&lt;p&gt;Thank you for taking the time to read! :)&lt;br&gt;
All of the stories are also available at my personal website - &lt;a href="https://anakidze.dev"&gt;https://anakidze.dev&lt;/a&gt;&lt;/p&gt;

</description>
      <category>webdev</category>
      <category>programming</category>
      <category>dotnet</category>
      <category>csharp</category>
    </item>
  </channel>
</rss>
