In my .net core console application, I am reading multiple excel files and bulk copy data into a database table. It is working as it is expected, I wonder if there are any improvements to make it better. So I would be glad if you can share your comments.
Thanks in advance.
class Program
{
static async Task Main(string[] args)
{
try
{
string s = null;
var d = new DirectoryInfo(@"C:\Test");
var files = d.GetFiles("*.xlsx");
var usersList = new List<User>();
foreach (var file in files)
{
var fileName = file.FullName;
using var package = new ExcelPackage(file);
ExcelPackage.LicenseContext = LicenseContext.NonCommercial;
var currentSheet = package.Workbook.Worksheets;
var workSheet = currentSheet.First();
var noOfCol = workSheet.Dimension.End.Column;
var noOfRow = workSheet.Dimension.End.Row;
for (int rowIterator = 2; rowIterator <= noOfRow; rowIterator++)
{
var user = new User
{
GameCode = workSheet.Cells[rowIterator, 1].Value?.ToString(),
Count = Convert.ToInt32(workSheet.Cells[rowIterator, 2].Value),
Email = workSheet.Cells[rowIterator, 3].Value?.ToString(),
Status = Convert.ToInt32(workSheet.Cells[rowIterator, 4].Value)
};
usersList.Add(user);
}
}
var conn = ConfigurationManager.ConnectionStrings["Development"].ConnectionString;
await using var connString = new SqlConnection(conn);
connString.Open();
await BulkWriter.InsertAsync(usersList, "[Orders]", connString, CancellationToken.None);
}
catch (Exception e)
{
Console.WriteLine(e);
throw;
}
}
private class BulkWriter
{
private static readonly ConcurrentDictionary<Type, SqlBulkCopyColumnMapping[]> ColumnMapping =
new ConcurrentDictionary<Type, SqlBulkCopyColumnMapping[]>();
public static async Task InsertAsync<T>(IEnumerable<T> items, string tableName, SqlConnection connection,
CancellationToken cancellationToken)
{
using var bulk = new SqlBulkCopy(connection);
await using var reader = ObjectReader.Create(items);
bulk.DestinationTableName = tableName;
foreach (var colMap in GetColumnMappings<T>())
bulk.ColumnMappings.Add(colMap);
await bulk.WriteToServerAsync(reader, cancellationToken);
}
private static IEnumerable<SqlBulkCopyColumnMapping> GetColumnMappings<T>() =>
ColumnMapping.GetOrAdd(typeof(T),
type =>
type.GetProperties()
.Select(p => new SqlBulkCopyColumnMapping(p.Name, p.Name)).ToArray());
}
}
Updated version:
I also added excel extension change and moving excel into another folder. Any comments?
public static class Program
{
private static async Task ReadAllExcelFilesInDirectory(string path, List<User> usersList)
{
var dirInfo = new DirectoryInfo(path);
var files = dirInfo.GetFiles("*.xlsx");
foreach (var file in files)
await ReadExcelFile(file, usersList);
}
private static async Task ReadExcelFile(FileInfo fileName, List<User> usersList)
{
const string destinationFile = @"T:\Test";
if (fileName == null) throw new ArgumentNullException(nameof(fileName));
if (usersList == null) throw new ArgumentNullException(nameof(usersList));
using var package = new ExcelPackage(fileName);
ExcelPackage.LicenseContext = LicenseContext.NonCommercial;
var currentSheet = package.Workbook.Worksheets;
var workSheet = currentSheet.First();
var noOfCol = workSheet.Dimension.End.Column;
var noOfRow = workSheet.Dimension.End.Row;
for (var rowIterator = 2; rowIterator <= noOfRow; rowIterator++)
{
var user = new User
{
GameCode = workSheet.Cells[rowIterator, 1].Value?.ToString(),
Count = Convert.ToInt32(workSheet.Cells[rowIterator, 2].Value),
Email = workSheet.Cells[rowIterator, 3].Value?.ToString(),
Status = Convert.ToInt32(workSheet.Cells[rowIterator, 4].Value)
};
usersList.Add(user);
}
//Change extension
await using var newfile = File.OpenWrite(fileName.FullName + ".old");
await package.SaveAsAsync(newfile);
// To move a file or folder to a new location
File.Move(fileName.FullName, destinationFile + "\\" + fileName.Name);
}
private static async Task InsertUsersIntoDatabase(List<User> usersList)
{
var conn = ConfigurationManager.ConnectionStrings["Development"].ConnectionString;
await using var connString = new SqlConnection(conn);
connString.Open();
await InsertAsync(usersList, "[GameAPI].[dbo].[A101Orders]", connString, CancellationToken.None);
}
private static async Task Main(string[] args)
{
try
{
var usersList = new List<User>();
await ReadAllExcelFilesInDirectory(
@"C:\Test", usersList);
await InsertUsersIntoDatabase(usersList);
}
catch (Exception e)
{
Console.WriteLine(e);
throw;
}
}
private static async Task InsertAsync<T>(IEnumerable<T> items, string tableName, SqlConnection connection,
CancellationToken cancellationToken)
{
using var bulk = new SqlBulkCopy(connection);
await using var reader = ObjectReader.Create(items);
bulk.DestinationTableName = tableName;
var properties = typeof(T).GetProperties();
foreach (var prop in properties)
bulk.ColumnMappings.Add(new SqlBulkCopyColumnMapping(prop.Name, prop.Name));
await bulk.WriteToServerAsync(reader, cancellationToken);
}
}
follow on questionwith a link to this question. \$\endgroup\$