<?xml version="1.0" encoding="utf-8" standalone="yes"?><rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom"><channel><title>DB Extensions</title><link>/</link><description>Recent content on DB Extensions</description><generator>Hugo</generator><language>en-US</language><copyright>Copyright (c) 2020-2026 ETLBoxperts GmbH</copyright><atom:link href="/index.xml" rel="self" type="application/rss+xml"/><item><title>Welcome to DbExtensions</title><link>/docs/getting-started/welcome/</link><pubDate>Mon, 01 Jan 0001 00:00:00 +0000</pubDate><guid>/docs/getting-started/welcome/</guid><description>&lt;h2 id="why-etlboxdbextensions"&gt;Why ETLBox.DbExtensions?&lt;/h2&gt;
&lt;p&gt;Dapper is excellent at reading data. It is not a bulk writer. The usual workaround — a loop of &lt;code&gt;INSERT&lt;/code&gt;/&lt;code&gt;UPDATE&lt;/code&gt;/&lt;code&gt;DELETE&lt;/code&gt; — is not only verbose. It costs one round-trip per row and gets slow as soon as the set grows.&lt;/p&gt;</description></item><item><title>Installation and Setup</title><link>/docs/getting-started/installation/</link><pubDate>Mon, 01 Jan 0001 00:00:00 +0000</pubDate><guid>/docs/getting-started/installation/</guid><description>&lt;h2 id="prerequisites"&gt;Prerequisites&lt;/h2&gt;
&lt;p&gt;Before you get started, make sure your environment meets the following requirements:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;ETLBox.DbExtensions supports all current .NET versions supported by Microsoft, including &lt;a href="https://dotnet.microsoft.com/" target="_blank" rel="noopener nofollow"&gt;.NET 8/9&lt;/a&gt; &lt;i class="small bi-box-arrow-up-right"&gt;&lt;/i&gt;&amp;nbsp;
 or later and .NET Framework 4.8.0 or later&lt;/li&gt;
&lt;li&gt;Required: A supported ETLBox database provider package, e.g. &lt;code&gt;ETLBox.SqlServer&lt;/code&gt; or &lt;code&gt;ETLBox.Postgres&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;Recommended IDEs: &lt;a href="https://visualstudio.microsoft.com/" target="_blank" rel="noopener nofollow"&gt;Visual Studio 2022&lt;/a&gt; &lt;i class="small bi-box-arrow-up-right"&gt;&lt;/i&gt;&amp;nbsp;
, &lt;a href="https://code.visualstudio.com/" target="_blank" rel="noopener nofollow"&gt;Visual Studio Code&lt;/a&gt; &lt;i class="small bi-box-arrow-up-right"&gt;&lt;/i&gt;&amp;nbsp;
, or &lt;a href="https://www.jetbrains.com/rider/" target="_blank" rel="noopener nofollow"&gt;JetBrains Rider&lt;/a&gt; &lt;i class="small bi-box-arrow-up-right"&gt;&lt;/i&gt;&amp;nbsp;
&lt;/li&gt;
&lt;li&gt;Basic knowledge of &lt;a href="https://dotnet.microsoft.com/en-us/learn/csharp" target="_blank" rel="noopener nofollow"&gt;C#&lt;/a&gt; &lt;i class="small bi-box-arrow-up-right"&gt;&lt;/i&gt;&amp;nbsp;
 and working with NuGet packages&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id="install-via-nuget"&gt;Install via NuGet&lt;/h2&gt;
&lt;p&gt;Add the following packages to your project:&lt;/p&gt;</description></item><item><title>Bulk Insert</title><link>/docs/operations/bulk-insert/</link><pubDate>Mon, 01 Jan 0001 00:00:00 +0000</pubDate><guid>/docs/operations/bulk-insert/</guid><description>&lt;p&gt;Use &lt;code&gt;BulkInsert&lt;/code&gt; when you would otherwise loop &lt;code&gt;INSERT&lt;/code&gt; statements — imports, staging loads, test data. On SQL Server this is SqlBulkCopy under the hood; you keep your POCOs instead of a &lt;code&gt;DataTable&lt;/code&gt;.&lt;/p&gt;</description></item><item><title>DbExtensions Overview</title><link>/docs/getting-started/overview/</link><pubDate>Mon, 01 Jan 0001 00:00:00 +0000</pubDate><guid>/docs/getting-started/overview/</guid><description>&lt;p&gt;&lt;strong&gt;ETLBox.DbExtensions&lt;/strong&gt; addresses this gap by adding high-performance bulk operations directly to &lt;code&gt;IDbConnection&lt;/code&gt;. It integrates cleanly with existing ADO.NET and Dapper workflows while keeping the API minimal and easy to adopt.&lt;/p&gt;</description></item><item><title>Bulk Update</title><link>/docs/operations/bulk-update/</link><pubDate>Mon, 01 Jan 0001 00:00:00 +0000</pubDate><guid>/docs/operations/bulk-update/</guid><description>&lt;p&gt;Use &lt;code&gt;BulkUpdate&lt;/code&gt; when many rows change at once (status flags, recalculated fields, sync from another system). Mark the key with &lt;code&gt;[IdColumn]&lt;/code&gt; (or set &lt;code&gt;IdColumns&lt;/code&gt; in options). A Dapper &lt;code&gt;UPDATE&lt;/code&gt; in a loop is simpler for a few rows and much slower for thousands.&lt;/p&gt;</description></item><item><title>Performance</title><link>/docs/getting-started/performance/</link><pubDate>Mon, 01 Jan 0001 00:00:00 +0000</pubDate><guid>/docs/getting-started/performance/</guid><description>&lt;h2 id="sql-server-5000-rows"&gt;SQL Server, 5,000 rows&lt;/h2&gt;
&lt;p&gt;Measured with the &lt;a href="https://github.com/etlbox/etlbox.demo/tree/main/DbExtensions.Benchmark" target="_blank" rel="noopener nofollow"&gt;DbExtensions.Benchmark&lt;/a&gt; &lt;i class="small bi-box-arrow-up-right"&gt;&lt;/i&gt;&amp;nbsp;
 project in &lt;code&gt;etlbox.demo&lt;/code&gt;. Release build, local SQL Server, catalog &lt;code&gt;demo&lt;/code&gt;. The Dapper baseline is one &lt;code&gt;Execute&lt;/code&gt; per row — the pattern you write when Dapper has no bulk API.&lt;/p&gt;</description></item><item><title>Bulk Delete</title><link>/docs/operations/bulk-delete/</link><pubDate>Mon, 01 Jan 0001 00:00:00 +0000</pubDate><guid>/docs/operations/bulk-delete/</guid><description>&lt;p&gt;Use &lt;code&gt;BulkDelete&lt;/code&gt; to remove a known set of keys without building a giant &lt;code&gt;IN (...)&lt;/code&gt; list or issuing one &lt;code&gt;DELETE&lt;/code&gt; per row. Identify rows with &lt;code&gt;[IdColumn]&lt;/code&gt; (or &lt;code&gt;IdColumns&lt;/code&gt; in options).&lt;/p&gt;</description></item><item><title>Compared to</title><link>/docs/getting-started/compared/</link><pubDate>Mon, 01 Jan 0001 00:00:00 +0000</pubDate><guid>/docs/getting-started/compared/</guid><description>&lt;h2 id="dapper"&gt;Dapper&lt;/h2&gt;
&lt;p&gt;Use Dapper for queries. Use DbExtensions when the next step is writing many rows.&lt;/p&gt;



&lt;div class="expressive-code"&gt;
 &lt;figure class="frame not-content"&gt;
 &lt;figcaption class="header"&gt;
 &lt;span class="title"&gt;&lt;/span&gt;
 &lt;/figcaption&gt;
 &lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-csharp" data-lang="csharp"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="k"&gt;using&lt;/span&gt; &lt;span class="nn"&gt;var&lt;/span&gt; &lt;span class="n"&gt;connection&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="n"&gt;SqlConnection&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;connectionString&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="kt"&gt;var&lt;/span&gt; &lt;span class="n"&gt;customers&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="n"&gt;connection&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Query&lt;/span&gt;&lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;Customer&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;(&lt;/span&gt;&lt;span class="s"&gt;&amp;#34;SELECT * FROM Customer WHERE Active = 1&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;ToList&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="n"&gt;connection&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;BulkUpdate&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;customers&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
 &lt;/figure&gt;
&lt;/div&gt;
&lt;p&gt;A &lt;code&gt;foreach&lt;/code&gt; + &lt;code&gt;Execute&lt;/code&gt; is fine for a handful of rows. At thousands of rows it is the 

&lt;a class="link link--text" href="/docs/getting-started/performance/"&gt;slow path we measured&lt;/a&gt;: one round-trip each. DbExtensions keeps your POCOs and the same connection.&lt;/p&gt;</description></item><item><title>Bulk Merge</title><link>/docs/operations/bulk-merge/</link><pubDate>Mon, 01 Jan 0001 00:00:00 +0000</pubDate><guid>/docs/operations/bulk-merge/</guid><description>&lt;p&gt;Use &lt;code&gt;BulkMerge&lt;/code&gt; when the source set should become the table (or a delta of it): insert missing rows, update existing ones, optionally delete rows that are no longer in the source. That is the operation where a Dapper select-then-insert-or-update loop hurts most.&lt;/p&gt;</description></item><item><title>Bulk Options</title><link>/docs/operations/bulk-options/</link><pubDate>Mon, 01 Jan 0001 00:00:00 +0000</pubDate><guid>/docs/operations/bulk-options/</guid><description>&lt;p&gt;This article describes all available options for &lt;code&gt;BulkInsert()&lt;/code&gt;, &lt;code&gt;BulkUpdate()&lt;/code&gt;, and &lt;code&gt;BulkDelete()&lt;/code&gt; via &lt;code&gt;BulkOptions&amp;lt;T&amp;gt;&lt;/code&gt;, and explains which options apply specifically to &lt;code&gt;BulkMerge()&lt;/code&gt; via &lt;code&gt;MergeBulkOptions&amp;lt;T&amp;gt;&lt;/code&gt;.&lt;/p&gt;</description></item></channel></rss>