June 02 2025
public class Product { public int ProductId { get; set; } public string Name { get; set; } public string Category { get; set; } public decimal Price { get; set; } public bool InStock { get; set; } }
Install-Package Z.Dapper.Plus Install-Package CsvHelper
DapperPlusManager.Entity<Product>() .Table("Products") // Table name in SQL Server .Map(p => p.ProductId) .Map(p => p.Name) .Map(p => p.Category) .Map(p => p.Price) .Map(p => p.InStock);
using CsvHelper; using System.Globalization; public static List<Product> ParseCsv(string filePath) { using var reader = new StreamReader(filePath); using var csv = new CsvReader(reader, CultureInfo.InvariantCulture); return csv.GetRecords<Product>().ToList(); }
public void ImportProducts(string csvFilePath, IDbConnection dbConnection) { var products = ParseCsv(csvFilePath); try { dbConnection.BulkInsert(products); Console.WriteLine($"{products.Count} products imported successfully."); } catch (Exception ex) { Console.WriteLine("Something went wrong during bulk insert: " + ex.Message); // Optional: log or retry } }
public async Task ImportProductsAsync( string csvFilePath, IDbConnection dbConnection, CancellationToken cancellationToken) { var products = ParseCsv(csvFilePath); try { cancellationToken.ThrowIfCancellationRequested(); await dbConnection.BulkInsertAsync(products, cancellationToken); Console.WriteLine($"{products.Count} products imported successfully (async)."); } catch (OperationCanceledException) { Console.WriteLine("Import was canceled."); } catch (Exception ex) { Console.WriteLine("Bulk insert failed: " + ex.Message); } }
products = products .Where(p => !string.IsNullOrWhiteSpace(p.Name) && p.Price >= 0) .ToList();
var invalidProducts = products.Where(p => p.Price < 0).ToList(); if (invalidProducts.Any()) { // show warning or log it }
public class ProductService { private readonly IDbConnection _connection; private readonly Random _random = new(); private static readonly string[] SampleNames = new[] { "Mouse", "Keyboard", "Monitor", "Speaker", "Tablet", "Webcam", "Laptop", "Headphones", "Microphone", "SSD" }; public ProductService(IDbConnection connection) { _connection = connection; } public List<Product> GenerateProducts(int count) { var list = new List<Product>(); for (int i = 0; i < count; i++) { list.Add(new Product { Name = SampleNames[_random.Next(SampleNames.Length)], Price = Math.Round((decimal)(_random.NextDouble() * 500), 2) }); } return list; } public async Task InsertWithDapperAsync(List<Product> products) { const string sql = "INSERT INTO Products (Name, Price) VALUES (@Name, @Price)"; foreach (var product in products) { await _connection.ExecuteAsync(sql, product); } } public async Task InsertWithDapperPlusAsync(List<Product> products) { await _connection.BulkInsertAsync(products); } }
DapperPlusManager.Entity<Product>() .Table("Products") .Map(p => p.Name) .Map(p => p.Price); // Register services builder.Services.AddSingleton<IDbConnection>(_ => { var conn = new SqliteConnection("Data Source=products.db"); Batteries.Init(); conn.Open(); EnsureDatabaseSchema(conn); return conn; });
app.MapPost("/seed/dapper", async (int count, ProductService service) => { var products = service.GenerateProducts(count); var sw = System.Diagnostics.Stopwatch.StartNew(); await service.InsertWithDapperAsync(products); sw.Stop(); return Results.Ok($"Inserted {count} records with Dapper in {sw.ElapsedMilliseconds}ms"); }); app.MapPost("/seed/dapperplus", async (int count, ProductService service) => { var products = service.GenerateProducts(count); var sw = System.Diagnostics.Stopwatch.StartNew(); await service.InsertWithDapperPlusAsync(products); sw.Stop(); return Results.Ok($"Inserted {count} records with Dapper Plus in {sw.ElapsedMilliseconds}ms"); });

1. Design Patterns that Deliver
This isn’t just another design patterns book. Dive into real-world examples and practical solutions to real problems in real applications.Check out it here.
Go-to resource for understanding the core concepts of design patterns without the overwhelming complexity. In this concise and affordable ebook, I've distilled the essence of design patterns into an easy-to-digest format. It is a Beginner level. Check out it here.
Every Monday morning, I share 1 actionable tip on C#, .NET & Arcitecture topic, that you can use right away.
Join 18,000+ subscribers to improve your .NET Knowledge.
Subscribe to the TheCodeMan.net and be among the 18,000+ subscribers gaining practical tips and resources to enhance your .NET expertise.