File Import Workflow
This guide shows a practical import path for taking delimited data from disk and preparing it for database upload.
The main value of this workflow is that the packages line up cleanly:
VersaTul.Data.FileReaderreads the file intoIDataReaderform.VersaTul.Data.Bulkgives you the transport-neutral bulk-copy contract and mapping model.VersaTul.Data.MsSqlbecomes the concrete upload step if SQL Server is the destination.
When To Use This Workflow
Use this workflow when you need to:
Import CSV or text files into a relational table.
Reuse the same import approach for one file or many files.
Keep parsing concerns separate from database upload concerns.
Packages To Install
dotnet add package VersaTul.Data.FileReader
dotnet add package VersaTul.Data.Bulk
dotnet add package VersaTul.Data.MsSql
Why These Packages Together
Data.FileReader solves file parsing.
Data.Bulk solves copy-detail and column-mapping structure.
Data.MsSql solves the actual SQL Server bulk upload.
That split is useful because you can reason about input parsing, mapping, and upload as separate concerns.
Step 1: Read The File
Start by turning the CSV file into an IDataReader.
using VersaTul.Data.FileReader;
var options = new FileOptions { HasHeader = true };
using var reader = fileReader.Read("C:\\imports", "people.csv", options);
if (reader == null)
{
throw new InvalidOperationException("The import file could not be opened.");
}
At this point the workflow is already in the right shape for bulk upload because the downstream packages operate on IDataReader.
Step 2: Define Column Mappings
Map the incoming columns to the destination table.
using VersaTul.Data.Bulk;
var copyDetail = new CopyDetail(
destinationName: "Persons",
reader: reader,
columnMappings: new[]
{
new BulkCopyColumnMapping<Person, Person>(model => model.Name, model => model.Name),
new BulkCopyColumnMapping<Person, Person>(model => model.Age, model => model.Age)
});
The mapping step is where you make schema intent explicit instead of burying it inside a larger import routine.
Step 3: Execute The Upload
If the destination is SQL Server, hand the prepared copy detail to the VersaTul.Data.MsSql bulk uploader.
using VersaTul.Data.MsSql.Bulk;
var result = await bulkCopy.DoCopyAsync(
new[] { copyDetail },
dBConnectionName: "AdventureWorks2019",
progressCallback: progress =>
{
Console.WriteLine($"Processed {progress.ProcessedItems} items");
});
What You Should See
When this workflow is wired correctly:
The file-reader step opens the file without custom parsing code in your service layer.
The bulk-copy step validates the mapping shape before upload.
The SQL Server upload reports progress and completes as one deliberate import operation.
Why This Workflow Helps Adoption
This is one of the clearest examples of VersaTul package composition providing real value.
You avoid writing:
a custom CSV parser,
a custom tabular-to-database mapper, and
a custom SQL Server bulk import wrapper.
Common Mistakes
Starting with
VersaTul.Data.Bulkwhen you still need a file parser.Starting with
VersaTul.Data.FileReaderbut not planning the upload target.Choosing
VersaTul.Data.Sqlinstead ofVersaTul.Data.MsSqlwhen SQL Server bulk upload is the real requirement.
What To Read Next
Read Data FileReader if you need more detail on file options and directory reads.
Read Data Bulk if you want deeper mapping and result-model detail.
Read SQL Data Access Workflow if your next step is building a reusable relational data-service layer around the import workflow.