Page cover image

DBDownloader

This class provides functionality for downloading data from a database and storing the result in a provided class. It supports multithreaded asynchronous calls, and allows for a queue of threaded download operations. It has automatic retry capability built in.

The type of DB Connection passed determines the database language it uses. You could for example provide a MySql connection instead.

It's like saying, "Hey downloader, I have a class with several properties I want filled from my database, take care of the rest".

Quick implementation

//Generate a connection string with custom properties set
string _CNS() => new SqlConnectionStringBuilder(c.GetConnectionString("main")) { Pooling = true, MaxPoolSize = 200, MultipleActiveResultSets = false, PacketSize = 32767 }.ToString();

//Create an instance of our data class with proeprties to hold results
var DataObject = new CircuitData();

//Allocate and assign with downloader extension.
var dl = Downloader.DBDownloader(DataObject, () => new SqlConnection(_CNS()))
    .Assign(f => f.circuits, "SELECT ID,Type,Name from dbo.Circuit", ConnectionPreExecute: "SET ARITHABORT ON")
    .Assign(f => f.circuitTypes, "SELECT * from util.CircuitType", ConnectionPreExecute: "SET ARITHABORT ON")
    
    //Wait can be called inline, or later! 
    //    You can proceed to do other operations until data is needed
    .Wait();

Console.WriteLine($"DL time: {dl.GetDownloadTime().TotalMilliseconds:F0}");

Downloader Extension

There is an easy way to create the DBDownloader by using the static extension method.

Downloader.DBDownloader(InClass, () => new Connection());

Assign / AssignSingle

Assigns the downloaded data to a property of the base object. Can be called multiple times using fluent syntax to fill multiple properties. The downloader automatically manages the multithreaded and asyhcnronous operations for filling each property.

It uses Dapper behind the scenes to perform the mapping and query execution. If you want to supply parameters, you can use the objectParam parameter.

If you're not assigning a list, but a single object, use AssignSingle().

Example:

var downloader = new DBDownloader<MyClass>(myInstance, connectionFactory);
downloader.Assign(x => x.PropertyName, "SELECT * FROM table");

Wait

Waits for all download tasks to complete. This can be called inline or later right before the downloaded data is required. It is thread blocking.

Example:

downloader.Wait();

GetDownloadTime

Gets the total time taken for all download tasks to complete.

Example:

TimeSpan totalTime = downloader.GetDownloadTime();

Downloads

You can get to the list of tasks created by accessing this property.

Every DownloadResult has properties for the success boolean, if an exception was thrown, the name of the property it set, and dates to indicate start and end times.

List<Task<DownloadResult>> Downloads;

Last updated